=back
+=head3 Changes since isl-0.10
+
+=over
+
+=item * The functions C<isl_set_dim_has_lower_bound> and
+C<isl_set_dim_has_upper_bound> have been renamed to
+C<isl_set_dim_has_any_lower_bound> and
+C<isl_set_dim_has_any_upper_bound>.
+
+=back
+
+=head1 License
+
+C<isl> is released under the MIT license.
+
+=over
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+of the Software, and to permit persons to whom the Software is furnished to do
+so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
+=back
+
+Note that C<isl> currently requires C<GMP>, which is released
+under the GNU Lesser General Public License (LGPL). This means
+that code linked against C<isl> is also linked against LGPL code.
+
=head1 Installation
The source of C<isl> can be obtained either as a tarball
=head2 Spaces
-Whenever a new set or relation is created from scratch,
+Whenever a new set, relation or similiar object is created from scratch,
the space in which it lives needs to be specified using an C<isl_space>.
+Each space involves zero or more parameters and zero, one or two
+tuples of set or input/output dimensions. The parameters and dimensions
+are identified by an C<isl_dim_type> and a position.
+The type C<isl_dim_param> refers to parameters,
+the type C<isl_dim_set> refers to set dimensions (for spaces
+with a single tuple of dimensions) and the types C<isl_dim_in>
+and C<isl_dim_out> refer to input and output dimensions
+(for spaces with two tuples of dimensions).
+Local spaces (see L</"Local Spaces">) also contain dimensions
+of type C<isl_dim_div>.
+Note that parameters are only identified by their position within
+a given object. Across different objects, parameters are (usually)
+identified by their names or identifiers. Only unnamed parameters
+are identified by their positions across objects. The use of unnamed
+parameters is discouraged.
#include <isl/space.h>
__isl_give isl_space *isl_space_alloc(isl_ctx *ctx,
__isl_give isl_space *isl_space_set_alloc(isl_ctx *ctx,
unsigned nparam, unsigned dim);
__isl_give isl_space *isl_space_copy(__isl_keep isl_space *space);
- void isl_space_free(__isl_take isl_space *space);
+ void *isl_space_free(__isl_take isl_space *space);
unsigned isl_space_dim(__isl_keep isl_space *space,
enum isl_dim_type type);
#include <isl/space.h>
int isl_space_is_params(__isl_keep isl_space *space);
int isl_space_is_set(__isl_keep isl_space *space);
+ int isl_space_is_map(__isl_keep isl_space *space);
+
+Spaces can be compared using the following functions:
+
+ #include <isl/space.h>
+ int isl_space_is_equal(__isl_keep isl_space *space1,
+ __isl_keep isl_space *space2);
+ int isl_space_is_domain(__isl_keep isl_space *space1,
+ __isl_keep isl_space *space2);
+ int isl_space_is_range(__isl_keep isl_space *space1,
+ __isl_keep isl_space *space2);
+
+C<isl_space_is_domain> checks whether the first argument is equal
+to the domain of the second argument. This requires in particular that
+the first argument is a set space and that the second argument
+is a map space.
It is often useful to create objects that live in the
same space as some other object. This can be accomplished
__isl_keep isl_pw_aff *pwaff);
__isl_give isl_space *isl_pw_aff_get_space(
__isl_keep isl_pw_aff *pwaff);
+ __isl_give isl_space *isl_multi_aff_get_domain_space(
+ __isl_keep isl_multi_aff *maff);
__isl_give isl_space *isl_multi_aff_get_space(
__isl_keep isl_multi_aff *maff);
__isl_give isl_space *isl_pw_multi_aff_get_domain_space(
int isl_local_space_is_set(__isl_keep isl_local_space *ls);
int isl_local_space_dim(__isl_keep isl_local_space *ls,
enum isl_dim_type type);
+ int isl_local_space_has_dim_id(
+ __isl_keep isl_local_space *ls,
+ enum isl_dim_type type, unsigned pos);
+ __isl_give isl_id *isl_local_space_get_dim_id(
+ __isl_keep isl_local_space *ls,
+ enum isl_dim_type type, unsigned pos);
int isl_local_space_has_dim_name(
__isl_keep isl_local_space *ls,
enum isl_dim_type type, unsigned pos)
__isl_give isl_printer *isl_printer_to_file(isl_ctx *ctx,
FILE *file);
__isl_give isl_printer *isl_printer_to_str(isl_ctx *ctx);
- void isl_printer_free(__isl_take isl_printer *printer);
+ void *isl_printer_free(__isl_take isl_printer *printer);
__isl_give char *isl_printer_get_str(
__isl_keep isl_printer *printer);
To actually print something, use
+ #include <isl/printer.h>
+ __isl_give isl_printer *isl_printer_print_double(
+ __isl_take isl_printer *p, double d);
+
#include <isl/set.h>
__isl_give isl_printer *isl_printer_print_basic_set(
__isl_take isl_printer *printer,
Sets and relations can be converted to union sets and relations
using the following functions.
- __isl_give isl_union_map *isl_union_map_from_map(
- __isl_take isl_map *map);
+ __isl_give isl_union_set *isl_union_set_from_basic_set(
+ __isl_take isl_basic_set *bset);
+ __isl_give isl_union_map *isl_union_map_from_basic_map(
+ __isl_take isl_basic_map *bmap);
__isl_give isl_union_set *isl_union_set_from_set(
__isl_take isl_set *set);
+ __isl_give isl_union_map *isl_union_map_from_map(
+ __isl_take isl_map *map);
The inverse conversions below can only be used if the input
union set or relation is known to contain elements in exactly one
__isl_give isl_union_map *isl_union_map_copy(
__isl_keep isl_union_map *umap);
void isl_basic_set_free(__isl_take isl_basic_set *bset);
- void isl_set_free(__isl_take isl_set *set);
+ void *isl_set_free(__isl_take isl_set *set);
void *isl_union_set_free(__isl_take isl_union_set *uset);
- void isl_basic_map_free(__isl_take isl_basic_map *bmap);
+ void *isl_basic_map_free(__isl_take isl_basic_map *bmap);
void isl_map_free(__isl_take isl_map *map);
void *isl_union_map_free(__isl_take isl_union_map *umap);
__isl_give isl_map *isl_map_remove_divs(
__isl_take isl_map *map);
+It is also possible to only remove those divs that are defined
+in terms of a given range of dimensions or only those for which
+no explicit representation is known.
+
+ __isl_give isl_basic_set *
+ isl_basic_set_remove_divs_involving_dims(
+ __isl_take isl_basic_set *bset,
+ enum isl_dim_type type,
+ unsigned first, unsigned n);
+ __isl_give isl_set *isl_set_remove_divs_involving_dims(
+ __isl_take isl_set *set, enum isl_dim_type type,
+ unsigned first, unsigned n);
+ __isl_give isl_map *isl_map_remove_divs_involving_dims(
+ __isl_take isl_map *map, enum isl_dim_type type,
+ unsigned first, unsigned n);
+
+ __isl_give isl_set *isl_set_remove_unknown_divs(
+ __isl_take isl_set *set);
+ __isl_give isl_map *isl_map_remove_unknown_divs(
+ __isl_take isl_map *map);
+
To iterate over all the sets or maps in a union set or map, use
int isl_union_set_foreach_set(__isl_keep isl_union_set *uset,
Similarly, the following functions can be used to check whether
a given dimension is involved in any lower or upper bound.
- int isl_set_dim_has_lower_bound(__isl_keep isl_set *set,
+ int isl_set_dim_has_any_lower_bound(__isl_keep isl_set *set,
enum isl_dim_type type, unsigned pos);
- int isl_set_dim_has_upper_bound(__isl_keep isl_set *set,
+ int isl_set_dim_has_any_upper_bound(__isl_keep isl_set *set,
enum isl_dim_type type, unsigned pos);
The identifiers or names of the domain and range spaces of a set
__isl_give isl_basic_map *isl_basic_map_set_tuple_name(
__isl_take isl_basic_map *bmap,
enum isl_dim_type type, const char *s);
+ int isl_map_has_tuple_name(__isl_keep isl_map *map,
+ enum isl_dim_type type);
const char *isl_map_get_tuple_name(
__isl_keep isl_map *map,
enum isl_dim_type type);
const char *isl_basic_map_get_dim_name(
__isl_keep isl_basic_map *bmap,
enum isl_dim_type type, unsigned pos);
+ int isl_map_has_dim_name(__isl_keep isl_map *map,
+ enum isl_dim_type type, unsigned pos);
const char *isl_map_get_dim_name(
__isl_keep isl_map *map,
enum isl_dim_type type, unsigned pos);
=item * Elimination
+ __isl_give isl_basic_set *isl_basic_set_eliminate(
+ __isl_take isl_basic_set *bset,
+ enum isl_dim_type type,
+ unsigned first, unsigned n);
__isl_give isl_set *isl_set_eliminate(
__isl_take isl_set *set, enum isl_dim_type type,
unsigned first, unsigned n);
=item * Aligning parameters
+ __isl_give isl_basic_set *isl_basic_set_align_params(
+ __isl_take isl_basic_set *bset,
+ __isl_take isl_space *model);
__isl_give isl_set *isl_set_align_params(
__isl_take isl_set *set,
__isl_take isl_space *model);
+ __isl_give isl_basic_map *isl_basic_map_align_params(
+ __isl_take isl_basic_map *bmap,
+ __isl_take isl_space *model);
__isl_give isl_map *isl_map_align_params(
__isl_take isl_map *map,
__isl_take isl_space *model);
__isl_give isl_map *isl_map_add_dims(
__isl_take isl_map *map,
enum isl_dim_type type, unsigned n);
+ __isl_give isl_basic_set *isl_basic_set_insert_dims(
+ __isl_take isl_basic_set *bset,
+ enum isl_dim_type type, unsigned pos,
+ unsigned n);
+ __isl_give isl_basic_map *isl_basic_map_insert_dims(
+ __isl_take isl_basic_map *bmap,
+ enum isl_dim_type type, unsigned pos,
+ unsigned n);
__isl_give isl_set *isl_set_insert_dims(
__isl_take isl_set *set,
enum isl_dim_type type, unsigned pos, unsigned n);
__isl_take isl_union_map *umap1,
__isl_take isl_union_map *umap2);
+The second argument to the C<_params> functions needs to be
+a parametric (basic) set. For the other functions, a parametric set
+for either argument is only allowed if the other argument is
+a parametric set as well.
+
=item * Union
__isl_give isl_set *isl_basic_set_union(
__isl_give isl_basic_map *isl_basic_map_range_product(
__isl_take isl_basic_map *bmap1,
__isl_take isl_basic_map *bmap2);
+ __isl_give isl_basic_map *isl_basic_map_product(
+ __isl_take isl_basic_map *bmap1,
+ __isl_take isl_basic_map *bmap2);
__isl_give isl_map *isl_map_domain_product(
__isl_take isl_map *map1,
__isl_take isl_map *map2);
__isl_give isl_map *isl_map_range_product(
__isl_take isl_map *map1,
__isl_take isl_map *map2);
+ __isl_give isl_union_map *isl_union_map_domain_product(
+ __isl_take isl_union_map *umap1,
+ __isl_take isl_union_map *umap2);
__isl_give isl_union_map *isl_union_map_range_product(
__isl_take isl_union_map *umap1,
__isl_take isl_union_map *umap2);
__isl_take isl_basic_map *bmap,
__isl_take isl_basic_set *dom,
__isl_give isl_set **empty);
+ __isl_give isl_pw_multi_aff *isl_map_lexmin_pw_multi_aff(
+ __isl_take isl_map *map);
+ __isl_give isl_pw_multi_aff *isl_map_lexmax_pw_multi_aff(
+ __isl_take isl_map *map);
=head2 Lists
Lists are defined over several element types, including
-C<isl_aff>, C<isl_pw_aff>, C<isl_basic_set> and C<isl_set>.
+C<isl_id>, C<isl_aff>, C<isl_pw_aff>, C<isl_basic_set> and C<isl_set>.
Here we take lists of C<isl_set>s as an example.
-Lists can be created, copied and freed using the following functions.
+Lists can be created, copied, modified and freed using the following functions.
#include <isl/list.h>
__isl_give isl_set_list *isl_set_list_from_set(
__isl_give isl_set_list *isl_set_list_add(
__isl_take isl_set_list *list,
__isl_take isl_set *el);
+ __isl_give isl_set_list *isl_set_list_drop(
+ __isl_take isl_set_list *list,
+ unsigned first, unsigned n);
+ __isl_give isl_set_list *isl_set_list_set_set(
+ __isl_take isl_set_list *list, int index,
+ __isl_take isl_set *set);
__isl_give isl_set_list *isl_set_list_concat(
__isl_take isl_set_list *list1,
__isl_take isl_set_list *list2);
__isl_give isl_id *isl_pw_aff_get_dim_id(
__isl_keep isl_pw_aff *pa,
enum isl_dim_type type, unsigned pos);
+ __isl_give isl_id *isl_pw_aff_get_tuple_id(
+ __isl_keep isl_pw_aff *pa,
+ enum isl_dim_type type);
int isl_aff_get_constant(__isl_keep isl_aff *aff,
isl_int *v);
int isl_aff_get_coefficient(__isl_keep isl_aff *aff,
__isl_take isl_aff *aff, isl_int v);
__isl_give isl_aff *isl_aff_add_constant_si(
__isl_take isl_aff *aff, int v);
+ __isl_give isl_aff *isl_aff_add_constant_num(
+ __isl_take isl_aff *aff, isl_int v);
+ __isl_give isl_aff *isl_aff_add_constant_num_si(
+ __isl_take isl_aff *aff, int v);
__isl_give isl_aff *isl_aff_add_coefficient(
__isl_take isl_aff *aff,
enum isl_dim_type type, int pos, isl_int v);
set the I<numerator> of the constant or coefficient, while
C<add_constant> and C<add_coefficient> add an integer value to
the possibly rational constant or coefficient.
+The C<add_constant_num> functions add an integer value to
+the numerator.
To check whether an affine expressions is obviously zero
or obviously equal to some other affine expression, use
to be a constant.
#include <isl/aff.h>
+ __isl_give isl_basic_set *isl_aff_neg_basic_set(
+ __isl_take isl_aff *aff);
__isl_give isl_basic_set *isl_aff_le_basic_set(
__isl_take isl_aff *aff1, __isl_take isl_aff *aff2);
__isl_give isl_basic_set *isl_aff_ge_basic_set(
__isl_take isl_pw_aff_list *list1,
__isl_take isl_pw_aff_list *list2);
+The function C<isl_aff_neg_basic_set> returns a basic set
+containing those elements in the domain space
+of C<aff> where C<aff> is negative.
The function C<isl_aff_ge_basic_set> returns a basic set
containing those elements in the shared space
of C<aff1> and C<aff2> where C<aff1> is greater than or equal to C<aff2>.
__isl_take isl_space *space);
__isl_give isl_multi_aff *isl_multi_aff_zero(
__isl_take isl_space *space);
+ __isl_give isl_multi_aff *isl_multi_aff_identity(
+ __isl_take isl_space *space);
__isl_give isl_pw_multi_aff *
isl_pw_multi_aff_from_multi_aff(
__isl_take isl_multi_aff *ma);
const char *isl_multi_aff_get_tuple_name(
__isl_keep isl_multi_aff *multi,
enum isl_dim_type type);
+ int isl_pw_multi_aff_has_tuple_name(
+ __isl_keep isl_pw_multi_aff *pma,
+ enum isl_dim_type type);
const char *isl_pw_multi_aff_get_tuple_name(
__isl_keep isl_pw_multi_aff *pma,
enum isl_dim_type type);
__isl_give isl_multi_aff *isl_multi_aff_drop_dims(
__isl_take isl_multi_aff *maff,
enum isl_dim_type type, unsigned first, unsigned n);
+ __isl_give isl_pw_multi_aff *isl_pw_multi_aff_drop_dims(
+ __isl_take isl_pw_multi_aff *pma,
+ enum isl_dim_type type, unsigned first, unsigned n);
To check whether two multiple affine expressions are
obviously equal to each other, use
Operations include
#include <isl/aff.h>
+ __isl_give isl_pw_multi_aff *isl_pw_multi_aff_union_lexmin(
+ __isl_take isl_pw_multi_aff *pma1,
+ __isl_take isl_pw_multi_aff *pma2);
+ __isl_give isl_pw_multi_aff *isl_pw_multi_aff_union_lexmax(
+ __isl_take isl_pw_multi_aff *pma1,
+ __isl_take isl_pw_multi_aff *pma2);
__isl_give isl_multi_aff *isl_multi_aff_add(
__isl_take isl_multi_aff *maff1,
__isl_take isl_multi_aff *maff2);
__isl_give isl_local_space **ls);
__isl_give isl_pw_multi_aff *isl_pw_multi_aff_coalesce(
__isl_take isl_pw_multi_aff *pma);
+ __isl_give isl_multi_aff *isl_multi_aff_align_params(
+ __isl_take isl_multi_aff *multi,
+ __isl_take isl_space *model);
+ __isl_give isl_pw_multi_aff *
+ isl_pw_multi_aff_project_domain_on_params(
+ __isl_take isl_pw_multi_aff *pma);
__isl_give isl_multi_aff *isl_multi_aff_gist_params(
__isl_take isl_multi_aff *maff,
__isl_take isl_set *context);
__isl_give isl_multi_aff *isl_multi_aff_flat_range_product(
__isl_take isl_multi_aff *ma1,
__isl_take isl_multi_aff *ma2);
+ __isl_give isl_multi_aff *isl_multi_aff_product(
+ __isl_take isl_multi_aff *ma1,
+ __isl_take isl_multi_aff *ma2);
__isl_give isl_pw_multi_aff *
isl_pw_multi_aff_flat_range_product(
__isl_take isl_pw_multi_aff *pma1,
__isl_take isl_pw_multi_aff *pma2);
+ __isl_give isl_pw_multi_aff *isl_pw_multi_aff_product(
+ __isl_take isl_pw_multi_aff *pma1,
+ __isl_take isl_pw_multi_aff *pma2);
__isl_give isl_union_pw_multi_aff *
isl_union_pw_multi_aff_flat_range_product(
__isl_take isl_union_pw_multi_aff *upma1,
then it is assigned the local space that lies at the basis of
the lifting applied.
+ __isl_give isl_set *isl_multi_aff_lex_le_set(
+ __isl_take isl_multi_aff *ma1,
+ __isl_take isl_multi_aff *ma2);
+ __isl_give isl_set *isl_multi_aff_lex_ge_set(
+ __isl_take isl_multi_aff *ma1,
+ __isl_take isl_multi_aff *ma2);
+
+The function C<isl_multi_aff_lex_le_set> returns a set
+containing those elements in the shared domain space
+where C<ma1> is lexicographically smaller than or
+equal to C<ma2>.
+
An expression can be read from input using
#include <isl/aff.h>
__isl_take isl_access_info *acc,
__isl_take isl_map *source, int must,
void *source_user);
- void isl_access_info_free(__isl_take isl_access_info *acc);
+ void *isl_access_info_free(__isl_take isl_access_info *acc);
__isl_give isl_flow *isl_access_info_compute_flow(
__isl_take isl_access_info *acc);
isl_ctx *ctx, int val);
int isl_options_get_schedule_max_constant_term(
isl_ctx *ctx);
+ int isl_options_set_schedule_fuse(isl_ctx *ctx, int val);
+ int isl_options_get_schedule_fuse(isl_ctx *ctx);
int isl_options_set_schedule_maximize_band_depth(
isl_ctx *ctx, int val);
int isl_options_get_schedule_maximize_band_depth(
isl_ctx *ctx, int val);
int isl_options_get_schedule_algorithm(
isl_ctx *ctx);
-
+ int isl_options_set_schedule_separate_components(
+ isl_ctx *ctx, int val);
+ int isl_options_get_schedule_separate_components(
+ isl_ctx *ctx);
=over
unrelated dimensions. A value of -1 means that this option does not introduce
bounds on the constant coefficients.
+=item * schedule_fuse
+
+This option controls the level of fusion.
+If this option is set to C<ISL_SCHEDULE_FUSE_MIN>, then loops in the
+resulting schedule will be distributed as much as possible.
+If this option is set to C<ISL_SCHEDULE_FUSE_MAX>, then C<isl> will
+try to fuse loops in the resulting schedule.
+
=item * schedule_maximize_band_depth
If this option is set, we do not split bands at the point
backtrack and split bands as early as possible. This
reduces the number of splits and maximizes the width of
the bands. Wider bands give more possibilities for tiling.
+Note that if the C<schedule_fuse> option is set to C<ISL_SCHEDULE_FUSE_MIN>,
+then bands will be split as early as possible, even if there is no need.
+The C<schedule_maximize_band_depth> option therefore has no effect in this case.
=item * schedule_outer_zero_distance
Available scheduling algorithms are C<ISL_SCHEDULE_ALGORITHM_ISL>
and C<ISL_SCHEDULE_ALGORITHM_FEAUTRIER>.
+=item * schedule_separate_components
+
+If at any point the dependence graph contains any (weakly connected) components,
+then these components are scheduled separately.
+If this option is not set, then some iterations of the domains
+in these components may be scheduled together.
+If this option is set, then the components are given consecutive
+schedules.
+
=back
=head2 Parametric Vertex Enumeration