/* * Each test case should name statements S_0, S_1, ... */ int test2() { printf("TEST 2\n"); isl_ctx *ctx = isl_ctx_alloc(); isl_union_set *domains = isl_union_set_read_from_str(ctx, "[p_0, p_1, p_2, p_3, p_4, p_5, p_7] -> { S_1[i0, i1] : i0 >= 0 and i0 <= p_0 and i1 >= 0 and i1 <= p_3 and p_2 >= 0; S_0[i0] : i0 >= 0 and i0 <= p_0}"); isl_union_map *deps = isl_union_map_read_from_str(ctx, "[p_0, p_1, p_2, p_3, p_4, p_5, p_7] -> { S_0[i0] -> S_1[o0, o1] : (exists (e0 = [(p_7)/8]: 8o1 = -p_5 + p_7 + 8192i0 - 8192o0 and 8e0 = p_7 and i0 >= 0 and o0 <= p_0 and 8192o0 >= -8p_3 - p_5 + p_7 + 8192i0 and 8192o0 <= -p_5 + p_7 + 8192i0 and p_2 >= 0 and o0 >= 1 + i0)); S_1[i0, i1] -> S_0[o0] : (exists (e0 = [(p_1)/8], e1 = [(p_4)/8], e2 = [(-p_1 + p_7)/8184]: 8192o0 = p_5 - p_7 + 8192i0 + 8i1 and 8e0 = p_1 and 8e1 = p_4 and 8184e2 = -p_1 + p_7 and i1 >= 0 and 8i1 <= 8192p_0 - p_5 + p_7 - 8192i0 and 8184i1 >= 1024 + 1024p_1 - 1023p_5 - p_7 - 8380416i0 and p_2 >= 0 and p_7 <= -1 + p_5 and 8i1 >= 1 + 8p_3 + p_4 - p_5 - 8192i0 and i1 <= p_3 and i0 >= 0 and 8i1 >= 8192 - p_5 + p_7))}"); isl_union_map *schedule = pluto_schedule(domains, deps, options); if (schedule) { isl_printer *printer = isl_printer_to_file(ctx, stdout); isl_printer_print_union_map(printer, schedule); printf("\n"); isl_printer_free(printer); // Check if the schedule can be applied to the domain. domains = isl_union_set_apply(domains, schedule); }else{ printf("No schedule\n"); } isl_union_set_free(domains); isl_union_map_free(deps); isl_ctx_free(ctx); }
/* Clear all memory allocated by "grouping". */ static void ppcg_grouping_clear(struct ppcg_grouping *grouping) { isl_union_map_free(grouping->dep); isl_union_set_free(grouping->domain); isl_union_pw_multi_aff_free(grouping->contraction); isl_schedule_free(grouping->schedule); }
/* Merge pairs of consecutive leaves in "leaves" taking into account * the intersection of validity and proximity schedule constraints "dep". * * If a leaf has been merged with the next leaf, then the combination * is checked again for merging with the next leaf. * That is, if the leaves are A, B and C, then B may not have been * merged with C, but after merging A and B, it could still be useful * to merge the combination AB with C. * * Two leaves A and B are merged if there are instances of at least * one pair of statements, one statement in A and one B, such that * the validity and proximity schedule constraints between them * make them suitable for merging according to check_merge. * * Return the final number of leaves in the sequence, or -1 on error. */ static int merge_leaves(int n, struct ppcg_grouping_leaf leaves[n], __isl_keep isl_union_map *dep) { int i; struct ppcg_merge_leaves_data data; for (i = n - 1; i >= 0; --i) { isl_union_map *dep_i; isl_stat ok; if (i + 1 >= n) continue; dep_i = isl_union_map_copy(dep); dep_i = isl_union_map_intersect_domain(dep_i, isl_union_set_copy(leaves[i].domain)); dep_i = isl_union_map_intersect_range(dep_i, isl_union_set_copy(leaves[i + 1].domain)); data.merge = 0; data.src = &leaves[i]; data.dst = &leaves[i + 1]; ok = isl_union_map_foreach_map(dep_i, &check_merge, &data); isl_union_map_free(dep_i); if (ok < 0 && !data.merge) return -1; if (!data.merge) continue; if (merge_pair(n, leaves, i) < 0) return -1; --n; ++i; } return n; }
/* Call isl_map_move_dims with the given arguments on each of the maps * in "umap" and return the union of the results. * * This function can only meaningfully be called on a union map * where all maps have the same space for both dst_type and src_type. * One of these should then be isl_dim_param as otherwise the union map * could only contain a single map. */ __isl_give isl_union_map *pet_union_map_move_dims( __isl_take isl_union_map *umap, enum isl_dim_type dst_type, unsigned dst_pos, enum isl_dim_type src_type, unsigned src_pos, unsigned n) { isl_space *space; struct pet_union_map_move_dims_data data = { dst_type, dst_pos, src_type, src_pos, n }; space = isl_union_map_get_space(umap); if (src_type == isl_dim_param) space = isl_space_drop_dims(space, src_type, src_pos, n); data.res = isl_union_map_empty(space); if (isl_union_map_foreach_map(umap, &map_move_dims, &data) < 0) data.res = isl_union_map_free(data.res); isl_union_map_free(umap); return data.res; }
/* Given a relation "map" between instances of two statements A and B, * are pairs of related instances executed together in the input schedule? * That is, is each pair of instances assigned the same value * by the corresponding prefix schedules? * * In particular, select the subset of "map" that has pairs of elements * with the same value for the prefix schedules and then check * if "map" is still a subset of the result. */ static isl_bool matches_prefix(__isl_keep isl_map *map, struct ppcg_grouping_leaf *src, struct ppcg_grouping_leaf *dst) { isl_union_map *umap, *equal; isl_multi_union_pw_aff *src_prefix, *dst_prefix, *prefix; isl_bool is_subset; src_prefix = isl_multi_union_pw_aff_copy(src->prefix); dst_prefix = isl_multi_union_pw_aff_copy(dst->prefix); prefix = isl_multi_union_pw_aff_union_add(src_prefix, dst_prefix); umap = isl_union_map_from_map(isl_map_copy(map)); equal = isl_union_map_copy(umap); equal = isl_union_map_eq_at_multi_union_pw_aff(equal, prefix); is_subset = isl_union_map_is_subset(umap, equal); isl_union_map_free(umap); isl_union_map_free(equal); return is_subset; }
/* Extend the ranges of the maps in the union map such they all have * the same dimension. */ __isl_give isl_union_map *align_range(__isl_take isl_union_map *umap) { struct align_range_data data; data.max_out = 0; isl_union_map_foreach_map(umap, &update_max_out, &data.max_out); data.res = isl_union_map_empty(isl_union_map_get_space(umap)); isl_union_map_foreach_map(umap, &map_align_range, &data); isl_union_map_free(umap); return data.res; }
void test1() { isl_ctx *ctx = isl_ctx_alloc(); isl_union_set *domains = isl_union_set_read_from_str(ctx, "[n] -> {S_1[i0, i1] : i0 >= 0 and i0 <= 99 and i1 >= 0 and i1 <= 99; S_0[i0] : i0 >= 0 and i0 <= 99; S_2[i0] : i0 >= 0 and i0 <= 99 }"); isl_union_map *deps = isl_union_map_read_from_str(ctx, "[n] -> {S_1[i0, 99] -> S_0[1 + i0] : i0 >= 0 and i0 <= 98; S_1[i0, i1] -> S_1[i0, 1 + i1] : i0 >= 0 and i0 <= 99 and i1 >= 0 and i1 <= 98; S_1[i0, 99] -> S_1[1 + i0, 0] : i0 >= 0 and i0 <= 98; S_0[i0] -> S_1[i0, 0] : i0 >= 0 and i0 <= 99; S_2[i0] -> S_1[1 + i0, 0] : i0 >= 0 and i0 <= 98; S_0[i0] -> S_2[i0] : i0 >= 0 and i0 <= 99; S_1[i0, 99] -> S_2[i0] : i0 >= 0 and i0 <= 99 }"); isl_union_map *schedule = pluto_schedule(domains, deps, options); isl_printer *printer = isl_printer_to_file(ctx, stdout); isl_printer_print_union_map(printer, schedule); printf("\n"); isl_printer_free(printer); // Check if the schedule can be applied to the domain. domains = isl_union_set_apply(domains, schedule); isl_union_set_free(domains); isl_union_map_free(deps); isl_ctx_free(ctx); }
static void isl_obj_union_map_free(void *v) { isl_union_map_free((isl_union_map *)v); }