1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289
|
#ifndef ISL_SCHEDULER_H
#define ISL_SCHEDULER_H
#include <isl/aff_type.h>
#include <isl/hash.h>
#include <isl/id_type.h>
#include <isl/map_type.h>
#include <isl/map_to_basic_set.h>
#include <isl/mat.h>
#include <isl/space_type.h>
#include <isl/set_type.h>
#include <isl/val_type.h>
#include <isl/vec.h>
#include <isl/union_map_type.h>
#include "isl_schedule_constraints.h"
#include "isl_tab.h"
/* Internal information about a node that is used during the construction
* of a schedule.
* space represents the original space in which the domain lives;
* that is, the space is not affected by compression
* sched is a matrix representation of the schedule being constructed
* for this node; if compressed is set, then this schedule is
* defined over the compressed domain space
* sched_map is an isl_map representation of the same (partial) schedule
* sched_map may be NULL; if compressed is set, then this map
* is defined over the uncompressed domain space
* rank is the number of linearly independent rows in the linear part
* of sched
* the rows of "vmap" represent a change of basis for the node
* variables; the first rank rows span the linear part of
* the schedule rows; the remaining rows are linearly independent
* the rows of "indep" represent linear combinations of the schedule
* coefficients that are non-zero when the schedule coefficients are
* linearly independent of previously computed schedule rows.
* start is the first variable in the LP problem in the sequences that
* represents the schedule coefficients of this node
* nvar is the dimension of the (compressed) domain
* nparam is the number of parameters or 0 if we are not constructing
* a parametric schedule
*
* If compressed is set, then hull represents the constraints
* that were used to derive the compression, while compress and
* decompress map the original space to the compressed space and
* vice versa.
*
* scc is the index of SCC (or WCC) this node belongs to
*
* "cluster" is only used inside extract_clusters and identifies
* the cluster of SCCs that the node belongs to.
*
* coincident contains a boolean for each of the rows of the schedule,
* indicating whether the corresponding scheduling dimension satisfies
* the coincidence constraints in the sense that the corresponding
* dependence distances are zero.
*
* If the schedule_treat_coalescing option is set, then
* "sizes" contains the sizes of the (compressed) instance set
* in each direction. If there is no fixed size in a given direction,
* then the corresponding size value is set to infinity.
* If the schedule_treat_coalescing option or the schedule_max_coefficient
* option is set, then "max" contains the maximal values for
* schedule coefficients of the (compressed) variables. If no bound
* needs to be imposed on a particular variable, then the corresponding
* value is negative.
* If not NULL, then "bounds" contains a non-parametric set
* in the compressed space that is bounded by the size in each direction.
*/
struct isl_sched_node {
isl_space *space;
int compressed;
isl_set *hull;
isl_multi_aff *compress;
isl_pw_multi_aff *decompress;
isl_mat *sched;
isl_map *sched_map;
int rank;
isl_mat *indep;
isl_mat *vmap;
int start;
int nvar;
int nparam;
int scc;
int cluster;
int *coincident;
isl_multi_val *sizes;
isl_basic_set *bounds;
isl_vec *max;
};
int isl_sched_node_scc_exactly(struct isl_sched_node *node, int scc);
isl_stat isl_sched_node_update_vmap(struct isl_sched_node *node);
__isl_give isl_multi_aff *isl_sched_node_extract_partial_schedule_multi_aff(
struct isl_sched_node *node, int first, int n);
/* An edge in the dependence graph. An edge may be used to
* ensure validity of the generated schedule, to minimize the dependence
* distance or both
*
* map is the dependence relation, with i -> j in the map if j depends on i
* tagged_condition and tagged_validity contain the union of all tagged
* condition or conditional validity dependence relations that
* specialize the dependence relation "map"; that is,
* if (i -> a) -> (j -> b) is an element of "tagged_condition"
* or "tagged_validity", then i -> j is an element of "map".
* If these fields are NULL, then they represent the empty relation.
* src is the source node
* dst is the sink node
*
* types is a bit vector containing the types of this edge.
* validity is set if the edge is used to ensure correctness
* coincidence is used to enforce zero dependence distances
* proximity is set if the edge is used to minimize dependence distances
* condition is set if the edge represents a condition
* for a conditional validity schedule constraint
* local can only be set for condition edges and indicates that
* the dependence distance over the edge should be zero
* conditional_validity is set if the edge is used to conditionally
* ensure correctness
*
* For validity edges, start and end mark the sequence of inequality
* constraints in the LP problem that encode the validity constraint
* corresponding to this edge.
*
* During clustering, an edge may be marked "no_merge" if it should
* not be used to merge clusters.
* The weight is also only used during clustering and it is
* an indication of how many schedule dimensions on either side
* of the schedule constraints can be aligned.
* If the weight is negative, then this means that this edge was postponed
* by has_bounded_distances or any_no_merge. The original weight can
* be retrieved by adding 1 + graph->max_weight, with "graph"
* the graph containing this edge.
*/
struct isl_sched_edge {
isl_map *map;
isl_union_map *tagged_condition;
isl_union_map *tagged_validity;
struct isl_sched_node *src;
struct isl_sched_node *dst;
unsigned types;
int start;
int end;
int no_merge;
int weight;
};
int isl_sched_edge_has_type(struct isl_sched_edge *edge,
enum isl_edge_type type);
int isl_sched_edge_is_condition(struct isl_sched_edge *edge);
int isl_sched_edge_is_conditional_validity(struct isl_sched_edge *edge);
int isl_sched_edge_scc_exactly(struct isl_sched_edge *edge, int scc);
int isl_sched_edge_is_proximity(struct isl_sched_edge *edge);
/* Internal information about the dependence graph used during
* the construction of the schedule.
*
* intra_hmap is a cache, mapping dependence relations to their dual,
* for dependences from a node to itself, possibly without
* coefficients for the parameters
* intra_hmap_param is a cache, mapping dependence relations to their dual,
* for dependences from a node to itself, including coefficients
* for the parameters
* inter_hmap is a cache, mapping dependence relations to their dual,
* for dependences between distinct nodes
* if compression is involved then the key for these maps
* is the original, uncompressed dependence relation, while
* the value is the dual of the compressed dependence relation.
*
* n is the number of nodes
* node is the list of nodes
* maxvar is the maximal number of variables over all nodes
* max_row is the allocated number of rows in the schedule
* n_row is the current (maximal) number of linearly independent
* rows in the node schedules
* n_total_row is the current number of rows in the node schedules
* band_start is the starting row in the node schedules of the current band
* root is set to the original dependence graph from which this graph
* is derived through splitting. If this graph is not the result of
* splitting, then the root field points to the graph itself.
*
* sorted contains a list of node indices sorted according to the
* SCC to which a node belongs
*
* n_edge is the number of edges
* edge is the list of edges
* max_edge contains the maximal number of edges of each type;
* in particular, it contains the number of edges in the inital graph.
* edge_table contains pointers into the edge array, hashed on the source
* and sink spaces; there is one such table for each type;
* a given edge may be referenced from more than one table
* if the corresponding relation appears in more than one of the
* sets of dependences; however, for each type there is only
* a single edge between a given pair of source and sink space
* in the entire graph
*
* node_table contains pointers into the node array, hashed on the space tuples
*
* region contains a list of variable sequences that should be non-trivial
*
* lp contains the (I)LP problem used to obtain new schedule rows
*
* src_scc and dst_scc are the source and sink SCCs of an edge with
* conflicting constraints
*
* scc represents the number of components
* weak is set if the components are weakly connected
*
* max_weight is used during clustering and represents the maximal
* weight of the relevant proximity edges.
*/
struct isl_sched_graph {
isl_map_to_basic_set *intra_hmap;
isl_map_to_basic_set *intra_hmap_param;
isl_map_to_basic_set *inter_hmap;
struct isl_sched_node *node;
int n;
int maxvar;
int max_row;
int n_row;
int *sorted;
int n_total_row;
int band_start;
struct isl_sched_graph *root;
struct isl_sched_edge *edge;
int n_edge;
int max_edge[isl_edge_last + 1];
struct isl_hash_table *edge_table[isl_edge_last + 1];
struct isl_hash_table *node_table;
struct isl_trivial_region *region;
isl_basic_set *lp;
int src_scc;
int dst_scc;
int scc;
int weak;
int max_weight;
};
isl_stat isl_sched_graph_init(struct isl_sched_graph *graph,
__isl_keep isl_schedule_constraints *sc);
void isl_sched_graph_free(isl_ctx *ctx, struct isl_sched_graph *graph);
int isl_sched_graph_is_node(struct isl_sched_graph *graph,
struct isl_sched_node *node);
isl_bool isl_sched_graph_has_validity_edge(struct isl_sched_graph *graph,
struct isl_sched_node *src, struct isl_sched_node *dst);
struct isl_sched_node *isl_sched_graph_find_node(isl_ctx *ctx,
struct isl_sched_graph *graph, __isl_keep isl_space *space);
isl_stat isl_sched_graph_detect_ccs(isl_ctx *ctx, struct isl_sched_graph *graph,
isl_bool (*follows)(int i, int j, void *user));
__isl_give isl_union_set *isl_sched_graph_extract_scc(isl_ctx *ctx,
struct isl_sched_graph *graph, int scc);
__isl_give isl_union_set_list *isl_sched_graph_extract_sccs(isl_ctx *ctx,
struct isl_sched_graph *graph);
isl_stat isl_sched_graph_extract_sub_graph(isl_ctx *ctx,
struct isl_sched_graph *graph,
int (*node_pred)(struct isl_sched_node *node, int data),
int (*edge_pred)(struct isl_sched_edge *edge, int data),
int data, struct isl_sched_graph *sub);
isl_stat isl_sched_graph_compute_maxvar(struct isl_sched_graph *graph);
isl_stat isl_schedule_node_compute_wcc_band(isl_ctx *ctx,
struct isl_sched_graph *graph);
__isl_give isl_schedule_node *isl_schedule_node_compute_finish_band(
__isl_take isl_schedule_node *node, struct isl_sched_graph *graph,
int initialized);
#endif
|