| =head1 Introduction |
| |
| C<isl> is a thread-safe C library for manipulating |
| sets and relations of integer points bounded by affine constraints. |
| The descriptions of the sets and relations may involve |
| both parameters and existentially quantified variables. |
| All computations are performed in exact integer arithmetic |
| using C<GMP> or C<imath>. |
| The C<isl> library offers functionality that is similar |
| to that offered by the C<Omega> and C<Omega+> libraries, |
| but the underlying algorithms are in most cases completely different. |
| |
| The library is by no means complete and some fairly basic |
| functionality is still missing. |
| Still, even in its current form, the library has been successfully |
| used as a backend polyhedral library for the polyhedral |
| scanner C<CLooG> and as part of an equivalence checker of |
| static affine programs. |
| For bug reports, feature requests and questions, |
| visit the discussion group at |
| L<http://groups.google.com/group/isl-development>. |
| |
| =head2 Backward Incompatible Changes |
| |
| =head3 Changes since isl-0.02 |
| |
| =over |
| |
| =item * The old printing functions have been deprecated |
| and replaced by C<isl_printer> functions, see L<Input and Output>. |
| |
| =item * Most functions related to dependence analysis have acquired |
| an extra C<must> argument. To obtain the old behavior, this argument |
| should be given the value 1. See L<Dependence Analysis>. |
| |
| =back |
| |
| =head3 Changes since isl-0.03 |
| |
| =over |
| |
| =item * The function C<isl_pw_qpolynomial_fold_add> has been |
| renamed to C<isl_pw_qpolynomial_fold_fold>. |
| Similarly, C<isl_union_pw_qpolynomial_fold_add> has been |
| renamed to C<isl_union_pw_qpolynomial_fold_fold>. |
| |
| =back |
| |
| =head3 Changes since isl-0.04 |
| |
| =over |
| |
| =item * All header files have been renamed from C<isl_header.h> |
| to C<isl/header.h>. |
| |
| =back |
| |
| =head3 Changes since isl-0.05 |
| |
| =over |
| |
| =item * The functions C<isl_printer_print_basic_set> and |
| C<isl_printer_print_basic_map> no longer print a newline. |
| |
| =item * The functions C<isl_flow_get_no_source> |
| and C<isl_union_map_compute_flow> now return |
| the accesses for which no source could be found instead of |
| the iterations where those accesses occur. |
| |
| =item * The functions C<isl_basic_map_identity> and |
| C<isl_map_identity> now take a B<map> space as input. An old call |
| C<isl_map_identity(space)> can be rewritten to |
| C<isl_map_identity(isl_space_map_from_set(space))>. |
| |
| =item * The function C<isl_map_power> no longer takes |
| a parameter position as input. Instead, the exponent |
| is now expressed as the domain of the resulting relation. |
| |
| =back |
| |
| =head3 Changes since isl-0.06 |
| |
| =over |
| |
| =item * The format of C<isl_printer_print_qpolynomial>'s |
| C<ISL_FORMAT_ISL> output has changed. |
| Use C<ISL_FORMAT_C> to obtain the old output. |
| |
| =item * The C<*_fast_*> functions have been renamed to C<*_plain_*>. |
| Some of the old names have been kept for backward compatibility, |
| but they will be removed in the future. |
| |
| =back |
| |
| =head3 Changes since isl-0.07 |
| |
| =over |
| |
| =item * The function C<isl_pw_aff_max> has been renamed to |
| C<isl_pw_aff_union_max>. |
| Similarly, the function C<isl_pw_aff_add> has been renamed to |
| C<isl_pw_aff_union_add>. |
| |
| =item * The C<isl_dim> type has been renamed to C<isl_space> |
| along with the associated functions. |
| Some of the old names have been kept for backward compatibility, |
| but they will be removed in the future. |
| |
| =item * Spaces of maps, sets and parameter domains are now |
| treated differently. The distinction between map spaces and set spaces |
| has always been made on a conceptual level, but proper use of such spaces |
| was never checked. Furthermore, up until isl-0.07 there was no way |
| of explicitly creating a parameter space. These can now be created |
| directly using C<isl_space_params_alloc> or from other spaces using |
| C<isl_space_params>. |
| |
| =item * The space in which C<isl_aff>, C<isl_pw_aff>, C<isl_qpolynomial>, |
| C<isl_pw_qpolynomial>, C<isl_qpolynomial_fold> and C<isl_pw_qpolynomial_fold> |
| objects live is now a map space |
| instead of a set space. This means, for example, that the dimensions |
| of the domain of an C<isl_aff> are now considered to be of type |
| C<isl_dim_in> instead of C<isl_dim_set>. Extra functions have been |
| added to obtain the domain space. Some of the constructors still |
| take a domain space and have therefore been renamed. |
| |
| =item * The functions C<isl_equality_alloc> and C<isl_inequality_alloc> |
| now take an C<isl_local_space> instead of an C<isl_space>. |
| An C<isl_local_space> can be created from an C<isl_space> |
| using C<isl_local_space_from_space>. |
| |
| =item * The C<isl_div> type has been removed. Functions that used |
| to return an C<isl_div> now return an C<isl_aff>. |
| Note that the space of an C<isl_aff> is that of relation. |
| When replacing a call to C<isl_div_get_coefficient> by a call to |
| C<isl_aff_get_coefficient> any C<isl_dim_set> argument needs |
| to be replaced by C<isl_dim_in>. |
| A call to C<isl_aff_from_div> can be replaced by a call |
| to C<isl_aff_floor>. |
| A call to C<isl_qpolynomial_div(div)> call be replaced by |
| the nested call |
| |
| isl_qpolynomial_from_aff(isl_aff_floor(div)) |
| |
| The function C<isl_constraint_div> has also been renamed |
| to C<isl_constraint_get_div>. |
| |
| =item * The C<nparam> argument has been removed from |
| C<isl_map_read_from_str> and similar functions. |
| When reading input in the original PolyLib format, |
| the result will have no parameters. |
| If parameters are expected, the caller may want to perform |
| dimension manipulation on the result. |
| |
| =back |
| |
| =head3 Changes since isl-0.09 |
| |
| =over |
| |
| =item * The C<schedule_split_parallel> option has been replaced |
| by the C<schedule_split_scaled> option. |
| |
| =item * The first argument of C<isl_pw_aff_cond> is now |
| an C<isl_pw_aff> instead of an C<isl_set>. |
| A call C<isl_pw_aff_cond(a, b, c)> can be replaced by |
| |
| isl_pw_aff_cond(isl_set_indicator_function(a), b, c) |
| |
| =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>. |
| The new C<isl_set_dim_has_lower_bound> and |
| C<isl_set_dim_has_upper_bound> have slightly different meanings. |
| |
| =back |
| |
| =head3 Changes since isl-0.12 |
| |
| =over |
| |
| =item * C<isl_int> has been replaced by C<isl_val>. |
| Some of the old functions are still available in C<isl/deprecated/*.h> |
| but they will be removed in the future. |
| |
| =item * The functions C<isl_pw_qpolynomial_eval>, |
| C<isl_union_pw_qpolynomial_eval>, C<isl_pw_qpolynomial_fold_eval> |
| and C<isl_union_pw_qpolynomial_fold_eval> have been changed to return |
| an C<isl_val> instead of an C<isl_qpolynomial>. |
| |
| =item * The function C<isl_band_member_is_zero_distance> |
| has been removed. Essentially the same functionality is available |
| through C<isl_band_member_is_coincident>, except that it requires |
| setting up coincidence constraints. |
| The option C<schedule_outer_zero_distance> has accordingly been |
| replaced by the option C<schedule_outer_coincidence>. |
| |
| =item * The function C<isl_vertex_get_expr> has been changed |
| to return an C<isl_multi_aff> instead of a rational C<isl_basic_set>. |
| The function C<isl_vertex_get_domain> has been changed to return |
| a regular basic set, rather than a rational basic set. |
| |
| =back |
| |
| =head3 Changes since isl-0.14 |
| |
| =over |
| |
| =item * The function C<isl_union_pw_multi_aff_add> now consistently |
| computes the sum on the shared definition domain. |
| The function C<isl_union_pw_multi_aff_union_add> has been added |
| to compute the sum on the union of definition domains. |
| The original behavior of C<isl_union_pw_multi_aff_add> was |
| confused and is no longer available. |
| |
| =item * Band forests have been replaced by schedule trees. |
| |
| =item * The function C<isl_union_map_compute_flow> has been |
| replaced by the function C<isl_union_access_info_compute_flow>. |
| Note that the may dependence relation returned by |
| C<isl_union_flow_get_may_dependence> is the union of |
| the two dependence relations returned by |
| C<isl_union_map_compute_flow>. Similarly for the no source relations. |
| The function C<isl_union_map_compute_flow> is still available |
| for backward compatibility, but it will be removed in the future. |
| |
| =item * The function C<isl_basic_set_drop_constraint> has been |
| deprecated. |
| |
| =item * The function C<isl_ast_build_ast_from_schedule> has been |
| renamed to C<isl_ast_build_node_from_schedule_map>. |
| The original name is still available |
| for backward compatibility, but it will be removed in the future. |
| |
| =item * The C<separation_class> AST generation option has been |
| deprecated. |
| |
| =item * The functions C<isl_equality_alloc> and C<isl_inequality_alloc> |
| have been renamed to C<isl_constraint_alloc_equality> and |
| C<isl_constraint_alloc_inequality>. The original names have been |
| kept for backward compatibility, but they will be removed in the future. |
| |
| =item * The C<schedule_fuse> option has been replaced |
| by the C<schedule_serialize_sccs> option. The effect |
| of setting the C<schedule_fuse> option to C<ISL_SCHEDULE_FUSE_MIN> |
| is now obtained by turning on the C<schedule_serialize_sccs> option. |
| |
| =back |
| |
| =head3 Changes since isl-0.17 |
| |
| =over |
| |
| =item * The function C<isl_printer_print_ast_expr> no longer prints |
| in C format by default. To print in C format, the output format |
| of the printer needs to have been explicitly set to C<ISL_FORMAT_C>. |
| As a result, the function C<isl_ast_expr_to_str> no longer prints |
| the expression in C format. Use C<isl_ast_expr_to_C_str> instead. |
| |
| =item * The functions C<isl_set_align_divs> and C<isl_map_align_divs> |
| have been deprecated. The function C<isl_set_lift> has an effect |
| that is similar to C<isl_set_align_divs> and could in some cases |
| be used as an alternative. |
| |
| =back |
| |
| =head3 Changes since isl-0.19 |
| |
| =over |
| |
| =item * Zero-dimensional objects of type C<isl_multi_pw_aff> or |
| C<isl_multi_union_pw_aff> can now keep track of an explicit domain. |
| This explicit domain, if present, is taken into account |
| by various operations that take such objects as input. |
| |
| =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 by default C<isl> 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. |
| |
| When configuring with C<--with-int=imath> or C<--with-int=imath-32>, C<isl> |
| will link against C<imath>, a library for exact integer arithmetic released |
| under the MIT license. |
| |
| =head1 Installation |
| |
| The source of C<isl> can be obtained either as a tarball |
| or from the git repository. Both are available from |
| L<http://isl.gforge.inria.fr/>. |
| The installation process depends on how you obtained |
| the source. |
| |
| =head2 Installation from the git repository |
| |
| =over |
| |
| =item 1 Clone or update the repository |
| |
| The first time the source is obtained, you need to clone |
| the repository. |
| |
| git clone git://repo.or.cz/isl.git |
| |
| To obtain updates, you need to pull in the latest changes |
| |
| git pull |
| |
| =item 2 Optionally get C<imath> submodule |
| |
| To build C<isl> with C<imath>, you need to obtain the C<imath> |
| submodule by running in the git source tree of C<isl> |
| |
| git submodule init |
| git submodule update |
| |
| This will fetch the required version of C<imath> in a subdirectory of C<isl>. |
| |
| =item 2 Generate C<configure> |
| |
| ./autogen.sh |
| |
| =back |
| |
| After performing the above steps, continue |
| with the L<Common installation instructions>. |
| |
| =head2 Common installation instructions |
| |
| =over |
| |
| =item 1 Obtain C<GMP> |
| |
| By default, building C<isl> requires C<GMP>, including its headers files. |
| Your distribution may not provide these header files by default |
| and you may need to install a package called C<gmp-devel> or something |
| similar. Alternatively, C<GMP> can be built from |
| source, available from L<http://gmplib.org/>. |
| C<GMP> is not needed if you build C<isl> with C<imath>. |
| |
| =item 2 Configure |
| |
| C<isl> uses the standard C<autoconf> C<configure> script. |
| To run it, just type |
| |
| ./configure |
| |
| optionally followed by some configure options. |
| A complete list of options can be obtained by running |
| |
| ./configure --help |
| |
| Below we discuss some of the more common options. |
| |
| =over |
| |
| =item C<--prefix> |
| |
| Installation prefix for C<isl> |
| |
| =item C<--with-int=[gmp|imath|imath-32]> |
| |
| Select the integer library to be used by C<isl>, the default is C<gmp>. |
| With C<imath-32>, C<isl> will use 32 bit integers, but fall back to C<imath> |
| for values out of the 32 bit range. In most applications, C<isl> will run |
| fastest with the C<imath-32> option, followed by C<gmp> and C<imath>, the |
| slowest. |
| |
| =item C<--with-gmp-prefix> |
| |
| Installation prefix for C<GMP> (architecture-independent files). |
| |
| =item C<--with-gmp-exec-prefix> |
| |
| Installation prefix for C<GMP> (architecture-dependent files). |
| |
| =back |
| |
| =item 3 Compile |
| |
| make |
| |
| =item 4 Install (optional) |
| |
| make install |
| |
| =back |
| |
| =head1 Integer Set Library |
| |
| =head2 Memory Management |
| |
| Since a high-level operation on isl objects usually involves |
| several substeps and since the user is usually not interested in |
| the intermediate results, most functions that return a new object |
| will also release all the objects passed as arguments. |
| If the user still wants to use one or more of these arguments |
| after the function call, she should pass along a copy of the |
| object rather than the object itself. |
| The user is then responsible for making sure that the original |
| object gets used somewhere else or is explicitly freed. |
| |
| The arguments and return values of all documented functions are |
| annotated to make clear which arguments are released and which |
| arguments are preserved. In particular, the following annotations |
| are used |
| |
| =over |
| |
| =item C<__isl_give> |
| |
| C<__isl_give> means that a new object is returned. |
| The user should make sure that the returned pointer is |
| used exactly once as a value for an C<__isl_take> argument. |
| In between, it can be used as a value for as many |
| C<__isl_keep> arguments as the user likes. |
| There is one exception, and that is the case where the |
| pointer returned is C<NULL>. Is this case, the user |
| is free to use it as an C<__isl_take> argument or not. |
| When applied to a C<char *>, the returned pointer needs to be |
| freed using C<free>. |
| |
| =item C<__isl_null> |
| |
| C<__isl_null> means that a C<NULL> value is returned. |
| |
| =item C<__isl_take> |
| |
| C<__isl_take> means that the object the argument points to |
| is taken over by the function and may no longer be used |
| by the user as an argument to any other function. |
| The pointer value must be one returned by a function |
| returning an C<__isl_give> pointer. |
| If the user passes in a C<NULL> value, then this will |
| be treated as an error in the sense that the function will |
| not perform its usual operation. However, it will still |
| make sure that all the other C<__isl_take> arguments |
| are released. |
| |
| =item C<__isl_keep> |
| |
| C<__isl_keep> means that the function will only use the object |
| temporarily. After the function has finished, the user |
| can still use it as an argument to other functions. |
| A C<NULL> value will be treated in the same way as |
| a C<NULL> value for an C<__isl_take> argument. |
| This annotation may also be used on return values of |
| type C<const char *>, in which case the returned pointer should |
| not be freed by the user and is only valid until the object |
| from which it was derived is updated or freed. |
| |
| =back |
| |
| =head2 Initialization |
| |
| All manipulations of integer sets and relations occur within |
| the context of an C<isl_ctx>. |
| A given C<isl_ctx> can only be used within a single thread. |
| All arguments of a function are required to have been allocated |
| within the same context. |
| There are currently no functions available for moving an object |
| from one C<isl_ctx> to another C<isl_ctx>. This means that |
| there is currently no way of safely moving an object from one |
| thread to another, unless the whole C<isl_ctx> is moved. |
| |
| An C<isl_ctx> can be allocated using C<isl_ctx_alloc> and |
| freed using C<isl_ctx_free>. |
| All objects allocated within an C<isl_ctx> should be freed |
| before the C<isl_ctx> itself is freed. |
| |
| isl_ctx *isl_ctx_alloc(); |
| void isl_ctx_free(isl_ctx *ctx); |
| |
| The user can impose a bound on the number of low-level I<operations> |
| that can be performed by an C<isl_ctx>. This bound can be set and |
| retrieved using the following functions. A bound of zero means that |
| no bound is imposed. The number of operations performed can be |
| reset using C<isl_ctx_reset_operations>. Note that the number |
| of low-level operations needed to perform a high-level computation |
| may differ significantly across different versions |
| of C<isl>, but it should be the same across different platforms |
| for the same version of C<isl>. |
| |
| Warning: This feature is experimental. C<isl> has good support to abort and |
| bail out during the computation, but this feature may exercise error code paths |
| that are normally not used that much. Consequently, it is not unlikely that |
| hidden bugs will be exposed. |
| |
| void isl_ctx_set_max_operations(isl_ctx *ctx, |
| unsigned long max_operations); |
| unsigned long isl_ctx_get_max_operations(isl_ctx *ctx); |
| void isl_ctx_reset_operations(isl_ctx *ctx); |
| |
| In order to be able to create an object in the same context |
| as another object, most object types (described later in |
| this document) provide a function to obtain the context |
| in which the object was created. |
| |
| #include <isl/val.h> |
| isl_ctx *isl_val_get_ctx(__isl_keep isl_val *val); |
| isl_ctx *isl_multi_val_get_ctx( |
| __isl_keep isl_multi_val *mv); |
| |
| #include <isl/id.h> |
| isl_ctx *isl_id_get_ctx(__isl_keep isl_id *id); |
| |
| #include <isl/local_space.h> |
| isl_ctx *isl_local_space_get_ctx( |
| __isl_keep isl_local_space *ls); |
| |
| #include <isl/set.h> |
| isl_ctx *isl_set_list_get_ctx( |
| __isl_keep isl_set_list *list); |
| |
| #include <isl/aff.h> |
| isl_ctx *isl_aff_get_ctx(__isl_keep isl_aff *aff); |
| isl_ctx *isl_multi_aff_get_ctx( |
| __isl_keep isl_multi_aff *maff); |
| isl_ctx *isl_pw_aff_get_ctx(__isl_keep isl_pw_aff *pa); |
| isl_ctx *isl_pw_multi_aff_get_ctx( |
| __isl_keep isl_pw_multi_aff *pma); |
| isl_ctx *isl_multi_pw_aff_get_ctx( |
| __isl_keep isl_multi_pw_aff *mpa); |
| isl_ctx *isl_union_pw_aff_get_ctx( |
| __isl_keep isl_union_pw_aff *upa); |
| isl_ctx *isl_union_pw_multi_aff_get_ctx( |
| __isl_keep isl_union_pw_multi_aff *upma); |
| isl_ctx *isl_multi_union_pw_aff_get_ctx( |
| __isl_keep isl_multi_union_pw_aff *mupa); |
| |
| #include <isl/id_to_ast_expr.h> |
| isl_ctx *isl_id_to_ast_expr_get_ctx( |
| __isl_keep isl_id_to_ast_expr *id2expr); |
| |
| #include <isl/point.h> |
| isl_ctx *isl_point_get_ctx(__isl_keep isl_point *pnt); |
| |
| #include <isl/vec.h> |
| isl_ctx *isl_vec_get_ctx(__isl_keep isl_vec *vec); |
| |
| #include <isl/mat.h> |
| isl_ctx *isl_mat_get_ctx(__isl_keep isl_mat *mat); |
| |
| #include <isl/vertices.h> |
| isl_ctx *isl_vertices_get_ctx( |
| __isl_keep isl_vertices *vertices); |
| isl_ctx *isl_vertex_get_ctx(__isl_keep isl_vertex *vertex); |
| isl_ctx *isl_cell_get_ctx(__isl_keep isl_cell *cell); |
| |
| #include <isl/flow.h> |
| isl_ctx *isl_restriction_get_ctx( |
| __isl_keep isl_restriction *restr); |
| isl_ctx *isl_union_access_info_get_ctx( |
| __isl_keep isl_union_access_info *access); |
| isl_ctx *isl_union_flow_get_ctx( |
| __isl_keep isl_union_flow *flow); |
| |
| #include <isl/schedule.h> |
| isl_ctx *isl_schedule_get_ctx( |
| __isl_keep isl_schedule *sched); |
| isl_ctx *isl_schedule_constraints_get_ctx( |
| __isl_keep isl_schedule_constraints *sc); |
| |
| #include <isl/schedule_node.h> |
| isl_ctx *isl_schedule_node_get_ctx( |
| __isl_keep isl_schedule_node *node); |
| |
| #include <isl/ast_build.h> |
| isl_ctx *isl_ast_build_get_ctx( |
| __isl_keep isl_ast_build *build); |
| |
| #include <isl/ast.h> |
| isl_ctx *isl_ast_expr_get_ctx( |
| __isl_keep isl_ast_expr *expr); |
| isl_ctx *isl_ast_node_get_ctx( |
| __isl_keep isl_ast_node *node); |
| |
| #include <isl/stride_info.h> |
| isl_ctx *isl_stride_info_get_ctx( |
| __isl_keep isl_stride_info *si); |
| |
| #include <isl/fixed_box.h> |
| isl_ctx *isl_fixed_box_get_ctx( |
| __isl_keep isl_fixed_box *box); |
| |
| =head2 Return Types |
| |
| C<isl> uses two special return types for functions that either return |
| a boolean or that in principle do not return anything. |
| In particular, the C<isl_bool> type has three possible values: |
| C<isl_bool_true> (a positive integer value), indicating I<true> or I<yes>; |
| C<isl_bool_false> (the integer value zero), indicating I<false> or I<no>; and |
| C<isl_bool_error> (a negative integer value), indicating that something |
| went wrong. The following function can be used to negate an C<isl_bool>, |
| where the negation of C<isl_bool_error> is C<isl_bool_error> again. |
| |
| #include <isl/val.h> |
| isl_bool isl_bool_not(isl_bool b); |
| |
| The C<isl_stat> type has two possible values: |
| C<isl_stat_ok> (the integer value zero), indicating a successful |
| operation; and |
| C<isl_stat_error> (a negative integer value), indicating that something |
| went wrong. |
| See L</"Error Handling"> for more information on |
| C<isl_bool_error> and C<isl_stat_error>. |
| |
| =head2 Values |
| |
| An C<isl_val> represents an integer value, a rational value |
| or one of three special values, infinity, negative infinity and NaN. |
| Some predefined values can be created using the following functions. |
| |
| #include <isl/val.h> |
| __isl_give isl_val *isl_val_zero(isl_ctx *ctx); |
| __isl_give isl_val *isl_val_one(isl_ctx *ctx); |
| __isl_give isl_val *isl_val_negone(isl_ctx *ctx); |
| __isl_give isl_val *isl_val_nan(isl_ctx *ctx); |
| __isl_give isl_val *isl_val_infty(isl_ctx *ctx); |
| __isl_give isl_val *isl_val_neginfty(isl_ctx *ctx); |
| |
| Specific integer values can be created using the following functions. |
| |
| #include <isl/val.h> |
| __isl_give isl_val *isl_val_int_from_si(isl_ctx *ctx, |
| long i); |
| __isl_give isl_val *isl_val_int_from_ui(isl_ctx *ctx, |
| unsigned long u); |
| __isl_give isl_val *isl_val_int_from_chunks(isl_ctx *ctx, |
| size_t n, size_t size, const void *chunks); |
| |
| The function C<isl_val_int_from_chunks> constructs an C<isl_val> |
| from the C<n> I<digits>, each consisting of C<size> bytes, stored at C<chunks>. |
| The least significant digit is assumed to be stored first. |
| |
| Value objects can be copied and freed using the following functions. |
| |
| #include <isl/val.h> |
| __isl_give isl_val *isl_val_copy(__isl_keep isl_val *v); |
| __isl_null isl_val *isl_val_free(__isl_take isl_val *v); |
| |
| They can be inspected using the following functions. |
| |
| #include <isl/val.h> |
| long isl_val_get_num_si(__isl_keep isl_val *v); |
| long isl_val_get_den_si(__isl_keep isl_val *v); |
| __isl_give isl_val *isl_val_get_den_val( |
| __isl_keep isl_val *v); |
| double isl_val_get_d(__isl_keep isl_val *v); |
| size_t isl_val_n_abs_num_chunks(__isl_keep isl_val *v, |
| size_t size); |
| int isl_val_get_abs_num_chunks(__isl_keep isl_val *v, |
| size_t size, void *chunks); |
| |
| C<isl_val_n_abs_num_chunks> returns the number of I<digits> |
| of C<size> bytes needed to store the absolute value of the |
| numerator of C<v>. |
| C<isl_val_get_abs_num_chunks> stores these digits at C<chunks>, |
| which is assumed to have been preallocated by the caller. |
| The least significant digit is stored first. |
| Note that C<isl_val_get_num_si>, C<isl_val_get_den_si>, |
| C<isl_val_get_d>, C<isl_val_n_abs_num_chunks> |
| and C<isl_val_get_abs_num_chunks> can only be applied to rational values. |
| |
| An C<isl_val> can be modified using the following function. |
| |
| #include <isl/val.h> |
| __isl_give isl_val *isl_val_set_si(__isl_take isl_val *v, |
| long i); |
| |
| The following unary properties are defined on C<isl_val>s. |
| |
| #include <isl/val.h> |
| int isl_val_sgn(__isl_keep isl_val *v); |
| isl_bool isl_val_is_zero(__isl_keep isl_val *v); |
| isl_bool isl_val_is_one(__isl_keep isl_val *v); |
| isl_bool isl_val_is_negone(__isl_keep isl_val *v); |
| isl_bool isl_val_is_nonneg(__isl_keep isl_val *v); |
| isl_bool isl_val_is_nonpos(__isl_keep isl_val *v); |
| isl_bool isl_val_is_pos(__isl_keep isl_val *v); |
| isl_bool isl_val_is_neg(__isl_keep isl_val *v); |
| isl_bool isl_val_is_int(__isl_keep isl_val *v); |
| isl_bool isl_val_is_rat(__isl_keep isl_val *v); |
| isl_bool isl_val_is_nan(__isl_keep isl_val *v); |
| isl_bool isl_val_is_infty(__isl_keep isl_val *v); |
| isl_bool isl_val_is_neginfty(__isl_keep isl_val *v); |
| |
| Note that the sign of NaN is undefined. |
| |
| The following binary properties are defined on pairs of C<isl_val>s. |
| |
| #include <isl/val.h> |
| isl_bool isl_val_lt(__isl_keep isl_val *v1, |
| __isl_keep isl_val *v2); |
| isl_bool isl_val_le(__isl_keep isl_val *v1, |
| __isl_keep isl_val *v2); |
| isl_bool isl_val_gt(__isl_keep isl_val *v1, |
| __isl_keep isl_val *v2); |
| isl_bool isl_val_ge(__isl_keep isl_val *v1, |
| __isl_keep isl_val *v2); |
| isl_bool isl_val_eq(__isl_keep isl_val *v1, |
| __isl_keep isl_val *v2); |
| isl_bool isl_val_ne(__isl_keep isl_val *v1, |
| __isl_keep isl_val *v2); |
| isl_bool isl_val_abs_eq(__isl_keep isl_val *v1, |
| __isl_keep isl_val *v2); |
| |
| Comparisons to NaN always return false. |
| That is, a NaN is not considered to hold any relative position |
| with respect to any value. In particular, a NaN |
| is neither considered to be equal to nor to be different from |
| any value (including another NaN). |
| The function C<isl_val_abs_eq> checks whether its two arguments |
| are equal in absolute value. |
| |
| For integer C<isl_val>s we additionally have the following binary property. |
| |
| #include <isl/val.h> |
| isl_bool isl_val_is_divisible_by(__isl_keep isl_val *v1, |
| __isl_keep isl_val *v2); |
| |
| An C<isl_val> can also be compared to an integer using the following |
| functions. The result of C<isl_val_cmp_si> undefined for NaN. |
| |
| #include <isl/val.h> |
| isl_bool isl_val_gt_si(__isl_keep isl_val *v, long i); |
| int isl_val_cmp_si(__isl_keep isl_val *v, long i); |
| |
| The following unary operations are available on C<isl_val>s. |
| |
| #include <isl/val.h> |
| __isl_give isl_val *isl_val_abs(__isl_take isl_val *v); |
| __isl_give isl_val *isl_val_neg(__isl_take isl_val *v); |
| __isl_give isl_val *isl_val_floor(__isl_take isl_val *v); |
| __isl_give isl_val *isl_val_ceil(__isl_take isl_val *v); |
| __isl_give isl_val *isl_val_trunc(__isl_take isl_val *v); |
| __isl_give isl_val *isl_val_inv(__isl_take isl_val *v); |
| __isl_give isl_val *isl_val_2exp(__isl_take isl_val *v); |
| |
| The following binary operations are available on C<isl_val>s. |
| |
| #include <isl/val.h> |
| __isl_give isl_val *isl_val_min(__isl_take isl_val *v1, |
| __isl_take isl_val *v2); |
| __isl_give isl_val *isl_val_max(__isl_take isl_val *v1, |
| __isl_take isl_val *v2); |
| __isl_give isl_val *isl_val_add(__isl_take isl_val *v1, |
| __isl_take isl_val *v2); |
| __isl_give isl_val *isl_val_add_ui(__isl_take isl_val *v1, |
| unsigned long v2); |
| __isl_give isl_val *isl_val_sub(__isl_take isl_val *v1, |
| __isl_take isl_val *v2); |
| __isl_give isl_val *isl_val_sub_ui(__isl_take isl_val *v1, |
| unsigned long v2); |
| __isl_give isl_val *isl_val_mul(__isl_take isl_val *v1, |
| __isl_take isl_val *v2); |
| __isl_give isl_val *isl_val_mul_ui(__isl_take isl_val *v1, |
| unsigned long v2); |
| __isl_give isl_val *isl_val_div(__isl_take isl_val *v1, |
| __isl_take isl_val *v2); |
| __isl_give isl_val *isl_val_div_ui(__isl_take isl_val *v1, |
| unsigned long v2); |
| |
| On integer values, we additionally have the following operations. |
| |
| #include <isl/val.h> |
| __isl_give isl_val *isl_val_2exp(__isl_take isl_val *v); |
| __isl_give isl_val *isl_val_mod(__isl_take isl_val *v1, |
| __isl_take isl_val *v2); |
| __isl_give isl_val *isl_val_gcd(__isl_take isl_val *v1, |
| __isl_take isl_val *v2); |
| __isl_give isl_val *isl_val_gcdext(__isl_take isl_val *v1, |
| __isl_take isl_val *v2, __isl_give isl_val **x, |
| __isl_give isl_val **y); |
| |
| The function C<isl_val_gcdext> returns the greatest common divisor g |
| of C<v1> and C<v2> as well as two integers C<*x> and C<*y> such |
| that C<*x> * C<v1> + C<*y> * C<v2> = g. |
| |
| =head3 GMP specific functions |
| |
| These functions are only available if C<isl> has been compiled with C<GMP> |
| support. |
| |
| Specific integer and rational values can be created from C<GMP> values using |
| the following functions. |
| |
| #include <isl/val_gmp.h> |
| __isl_give isl_val *isl_val_int_from_gmp(isl_ctx *ctx, |
| mpz_t z); |
| __isl_give isl_val *isl_val_from_gmp(isl_ctx *ctx, |
| const mpz_t n, const mpz_t d); |
| |
| The numerator and denominator of a rational value can be extracted as |
| C<GMP> values using the following functions. |
| |
| #include <isl/val_gmp.h> |
| int isl_val_get_num_gmp(__isl_keep isl_val *v, mpz_t z); |
| int isl_val_get_den_gmp(__isl_keep isl_val *v, mpz_t z); |
| |
| =head2 Sets and Relations |
| |
| C<isl> uses six types of objects for representing sets and relations, |
| C<isl_basic_set>, C<isl_basic_map>, C<isl_set>, C<isl_map>, |
| C<isl_union_set> and C<isl_union_map>. |
| C<isl_basic_set> and C<isl_basic_map> represent sets and relations that |
| can be described as a conjunction of affine constraints, while |
| C<isl_set> and C<isl_map> represent unions of |
| C<isl_basic_set>s and C<isl_basic_map>s, respectively. |
| However, all C<isl_basic_set>s or C<isl_basic_map>s in the union need |
| to live in the same space. C<isl_union_set>s and C<isl_union_map>s |
| represent unions of C<isl_set>s or C<isl_map>s in I<different> spaces, |
| where spaces are considered different if they have a different number |
| of dimensions and/or different names (see L<"Spaces">). |
| The difference between sets and relations (maps) is that sets have |
| one set of variables, while relations have two sets of variables, |
| input variables and output variables. |
| |
| =head2 Error Handling |
| |
| C<isl> supports different ways to react in case a runtime error is triggered. |
| Runtime errors arise, e.g., if a function such as C<isl_map_intersect> is called |
| with two maps that have incompatible spaces. There are three possible ways |
| to react on error: to warn, to continue or to abort. |
| |
| The default behavior is to warn. In this mode, C<isl> prints a warning, stores |
| the last error in the corresponding C<isl_ctx> and the function in which the |
| error was triggered returns a value indicating that some error has |
| occurred. In case of functions returning a pointer, this value is |
| C<NULL>. In case of functions returning an C<isl_bool> or an |
| C<isl_stat>, this value is C<isl_bool_error> or C<isl_stat_error>. |
| An error does not corrupt internal state, |
| such that isl can continue to be used. C<isl> also provides functions to |
| read the last error, including the specific error message, |
| the isl source file where the error occurred and the line number, |
| and to reset all information about the last error. The |
| last error is only stored for information purposes. Its presence does not |
| change the behavior of C<isl>. Hence, resetting an error is not required to |
| continue to use isl, but only to observe new errors. |
| |
| #include <isl/ctx.h> |
| enum isl_error isl_ctx_last_error(isl_ctx *ctx); |
| const char *isl_ctx_last_error_msg(isl_ctx *ctx); |
| const char *isl_ctx_last_error_file(isl_ctx *ctx); |
| int isl_ctx_last_error_line(isl_ctx *ctx); |
| void isl_ctx_reset_error(isl_ctx *ctx); |
| |
| If no error has occurred since the last call to C<isl_ctx_reset_error>, |
| then the functions C<isl_ctx_last_error_msg> and |
| C<isl_ctx_last_error_file> return C<NULL>. |
| |
| Another option is to continue on error. This is similar to warn on error mode, |
| except that C<isl> does not print any warning. This allows a program to |
| implement its own error reporting. |
| |
| The last option is to directly abort the execution of the program from within |
| the isl library. This makes it obviously impossible to recover from an error, |
| but it allows to directly spot the error location. By aborting on error, |
| debuggers break at the location the error occurred and can provide a stack |
| trace. Other tools that automatically provide stack traces on abort or that do |
| not want to continue execution after an error was triggered may also prefer to |
| abort on error. |
| |
| The on error behavior of isl can be specified by calling |
| C<isl_options_set_on_error> or by setting the command line option |
| C<--isl-on-error>. Valid arguments for the function call are |
| C<ISL_ON_ERROR_WARN>, C<ISL_ON_ERROR_CONTINUE> and C<ISL_ON_ERROR_ABORT>. The |
| choices for the command line option are C<warn>, C<continue> and C<abort>. |
| It is also possible to query the current error mode. |
| |
| #include <isl/options.h> |
| isl_stat isl_options_set_on_error(isl_ctx *ctx, int val); |
| int isl_options_get_on_error(isl_ctx *ctx); |
| |
| =head2 Identifiers |
| |
| Identifiers are used to identify both individual dimensions |
| and tuples of dimensions. They consist of an optional name and an optional |
| user pointer. The name and the user pointer cannot both be C<NULL>, however. |
| Identifiers with the same name but different pointer values |
| are considered to be distinct. |
| Similarly, identifiers with different names but the same pointer value |
| are also considered to be distinct. |
| Equal identifiers are represented using the same object. |
| Pairs of identifiers can therefore be tested for equality using the |
| C<==> operator. |
| Identifiers can be constructed, copied, freed, inspected and printed |
| using the following functions. |
| |
| #include <isl/id.h> |
| __isl_give isl_id *isl_id_alloc(isl_ctx *ctx, |
| __isl_keep const char *name, void *user); |
| __isl_give isl_id *isl_id_set_free_user( |
| __isl_take isl_id *id, |
| void (*free_user)(void *user)); |
| __isl_give isl_id *isl_id_copy(isl_id *id); |
| __isl_null isl_id *isl_id_free(__isl_take isl_id *id); |
| |
| void *isl_id_get_user(__isl_keep isl_id *id); |
| __isl_keep const char *isl_id_get_name(__isl_keep isl_id *id); |
| |
| __isl_give isl_printer *isl_printer_print_id( |
| __isl_take isl_printer *p, __isl_keep isl_id *id); |
| |
| The callback set by C<isl_id_set_free_user> is called on the user |
| pointer when the last reference to the C<isl_id> is freed. |
| Note that C<isl_id_get_name> returns a pointer to some internal |
| data structure, so the result can only be used while the |
| corresponding C<isl_id> is alive. |
| |
| =head2 Spaces |
| |
| Whenever a new set, relation or similar 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, |
| unsigned nparam, unsigned n_in, unsigned n_out); |
| __isl_give isl_space *isl_space_params_alloc(isl_ctx *ctx, |
| unsigned nparam); |
| __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); |
| __isl_null isl_space *isl_space_free(__isl_take isl_space *space); |
| |
| The space used for creating a parameter domain |
| needs to be created using C<isl_space_params_alloc>. |
| For other sets, the space |
| needs to be created using C<isl_space_set_alloc>, while |
| for a relation, the space |
| needs to be created using C<isl_space_alloc>. |
| |
| To check whether a given space is that of a set or a map |
| or whether it is a parameter space, use these functions: |
| |
| #include <isl/space.h> |
| isl_bool isl_space_is_params(__isl_keep isl_space *space); |
| isl_bool isl_space_is_set(__isl_keep isl_space *space); |
| isl_bool isl_space_is_map(__isl_keep isl_space *space); |
| |
| Spaces can be compared using the following functions: |
| |
| #include <isl/space.h> |
| isl_bool isl_space_is_equal(__isl_keep isl_space *space1, |
| __isl_keep isl_space *space2); |
| isl_bool isl_space_has_equal_params( |
| __isl_keep isl_space *space1, |
| __isl_keep isl_space *space2); |
| isl_bool isl_space_has_equal_tuples( |
| __isl_keep isl_space *space1, |
| __isl_keep isl_space *space2); |
| isl_bool isl_space_is_domain(__isl_keep isl_space *space1, |
| __isl_keep isl_space *space2); |
| isl_bool isl_space_is_range(__isl_keep isl_space *space1, |
| __isl_keep isl_space *space2); |
| isl_bool isl_space_tuple_is_equal( |
| __isl_keep isl_space *space1, |
| enum isl_dim_type type1, |
| __isl_keep isl_space *space2, |
| enum isl_dim_type type2); |
| |
| 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. C<isl_space_tuple_is_equal> checks whether the given |
| tuples (C<isl_dim_in>, C<isl_dim_out> or C<isl_dim_set>) of the given |
| spaces are the same. That is, it checks if they have the same |
| identifier (if any), the same dimension and the same internal structure |
| (if any). |
| The function |
| C<isl_space_has_equal_params> checks whether two spaces |
| have the same parameters in the same order. |
| C<isl_space_has_equal_tuples> check whether two spaces have |
| the same tuples. In contrast to C<isl_space_is_equal> below, |
| it does not check the |
| parameters. This is useful because many C<isl> functions align the |
| parameters before they perform their operations, such that equivalence |
| is not necessary. |
| C<isl_space_is_equal> checks whether two spaces are identical, |
| meaning that they have the same parameters and the same tuples. |
| That is, it checks whether both C<isl_space_has_equal_params> and |
| C<isl_space_has_equal_tuples> hold. |
| |
| It is often useful to create objects that live in the |
| same space as some other object. This can be accomplished |
| by creating the new objects |
| (see L</"Creating New Sets and Relations"> or |
| L</"Functions">) based on the space |
| of the original object. |
| |
| #include <isl/set.h> |
| __isl_give isl_space *isl_basic_set_get_space( |
| __isl_keep isl_basic_set *bset); |
| __isl_give isl_space *isl_set_get_space(__isl_keep isl_set *set); |
| |
| #include <isl/union_set.h> |
| __isl_give isl_space *isl_union_set_get_space( |
| __isl_keep isl_union_set *uset); |
| |
| #include <isl/map.h> |
| __isl_give isl_space *isl_basic_map_get_space( |
| __isl_keep isl_basic_map *bmap); |
| __isl_give isl_space *isl_map_get_space(__isl_keep isl_map *map); |
| |
| #include <isl/union_map.h> |
| __isl_give isl_space *isl_union_map_get_space( |
| __isl_keep isl_union_map *umap); |
| |
| #include <isl/constraint.h> |
| __isl_give isl_space *isl_constraint_get_space( |
| __isl_keep isl_constraint *constraint); |
| |
| #include <isl/polynomial.h> |
| __isl_give isl_space *isl_qpolynomial_get_domain_space( |
| __isl_keep isl_qpolynomial *qp); |
| __isl_give isl_space *isl_qpolynomial_get_space( |
| __isl_keep isl_qpolynomial *qp); |
| __isl_give isl_space * |
| isl_qpolynomial_fold_get_domain_space( |
| __isl_keep isl_qpolynomial_fold *fold); |
| __isl_give isl_space *isl_qpolynomial_fold_get_space( |
| __isl_keep isl_qpolynomial_fold *fold); |
| __isl_give isl_space *isl_pw_qpolynomial_get_domain_space( |
| __isl_keep isl_pw_qpolynomial *pwqp); |
| __isl_give isl_space *isl_pw_qpolynomial_get_space( |
| __isl_keep isl_pw_qpolynomial *pwqp); |
| __isl_give isl_space *isl_pw_qpolynomial_fold_get_domain_space( |
| __isl_keep isl_pw_qpolynomial_fold *pwf); |
| __isl_give isl_space *isl_pw_qpolynomial_fold_get_space( |
| __isl_keep isl_pw_qpolynomial_fold *pwf); |
| __isl_give isl_space *isl_union_pw_qpolynomial_get_space( |
| __isl_keep isl_union_pw_qpolynomial *upwqp); |
| __isl_give isl_space *isl_union_pw_qpolynomial_fold_get_space( |
| __isl_keep isl_union_pw_qpolynomial_fold *upwf); |
| |
| #include <isl/val.h> |
| __isl_give isl_space *isl_multi_val_get_space( |
| __isl_keep isl_multi_val *mv); |
| |
| #include <isl/aff.h> |
| __isl_give isl_space *isl_aff_get_domain_space( |
| __isl_keep isl_aff *aff); |
| __isl_give isl_space *isl_aff_get_space( |
| __isl_keep isl_aff *aff); |
| __isl_give isl_space *isl_pw_aff_get_domain_space( |
| __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( |
| __isl_keep isl_pw_multi_aff *pma); |
| __isl_give isl_space *isl_pw_multi_aff_get_space( |
| __isl_keep isl_pw_multi_aff *pma); |
| __isl_give isl_space *isl_union_pw_aff_get_space( |
| __isl_keep isl_union_pw_aff *upa); |
| __isl_give isl_space *isl_union_pw_multi_aff_get_space( |
| __isl_keep isl_union_pw_multi_aff *upma); |
| __isl_give isl_space *isl_multi_pw_aff_get_domain_space( |
| __isl_keep isl_multi_pw_aff *mpa); |
| __isl_give isl_space *isl_multi_pw_aff_get_space( |
| __isl_keep isl_multi_pw_aff *mpa); |
| __isl_give isl_space * |
| isl_multi_union_pw_aff_get_domain_space( |
| __isl_keep isl_multi_union_pw_aff *mupa); |
| __isl_give isl_space * |
| isl_multi_union_pw_aff_get_space( |
| __isl_keep isl_multi_union_pw_aff *mupa); |
| |
| #include <isl/point.h> |
| __isl_give isl_space *isl_point_get_space( |
| __isl_keep isl_point *pnt); |
| |
| #include <isl/fixed_box.h> |
| __isl_give isl_space *isl_fixed_box_get_space( |
| __isl_keep isl_fixed_box *box); |
| |
| The number of dimensions of a given type of space |
| may be read off from a space or an object that lives |
| in a space using the following functions. |
| In case of C<isl_space_dim>, type may be |
| C<isl_dim_param>, C<isl_dim_in> (only for relations), |
| C<isl_dim_out> (only for relations), C<isl_dim_set> |
| (only for sets) or C<isl_dim_all>. |
| |
| #include <isl/space.h> |
| unsigned isl_space_dim(__isl_keep isl_space *space, |
| enum isl_dim_type type); |
| |
| #include <isl/local_space.h> |
| int isl_local_space_dim(__isl_keep isl_local_space *ls, |
| enum isl_dim_type type); |
| |
| #include <isl/set.h> |
| unsigned isl_basic_set_dim(__isl_keep isl_basic_set *bset, |
| enum isl_dim_type type); |
| unsigned isl_set_dim(__isl_keep isl_set *set, |
| enum isl_dim_type type); |
| |
| #include <isl/union_set.h> |
| unsigned isl_union_set_dim(__isl_keep isl_union_set *uset, |
| enum isl_dim_type type); |
| |
| #include <isl/map.h> |
| unsigned isl_basic_map_dim(__isl_keep isl_basic_map *bmap, |
| enum isl_dim_type type); |
| unsigned isl_map_dim(__isl_keep isl_map *map, |
| enum isl_dim_type type); |
| |
| #include <isl/union_map.h> |
| unsigned isl_union_map_dim(__isl_keep isl_union_map *umap, |
| enum isl_dim_type type); |
| |
| #include <isl/val.h> |
| unsigned isl_multi_val_dim(__isl_keep isl_multi_val *mv, |
| enum isl_dim_type type); |
| |
| #include <isl/aff.h> |
| int isl_aff_dim(__isl_keep isl_aff *aff, |
| enum isl_dim_type type); |
| unsigned isl_multi_aff_dim(__isl_keep isl_multi_aff *maff, |
| enum isl_dim_type type); |
| unsigned isl_pw_aff_dim(__isl_keep isl_pw_aff *pwaff, |
| enum isl_dim_type type); |
| unsigned isl_pw_multi_aff_dim( |
| __isl_keep isl_pw_multi_aff *pma, |
| enum isl_dim_type type); |
| unsigned isl_multi_pw_aff_dim( |
| __isl_keep isl_multi_pw_aff *mpa, |
| enum isl_dim_type type); |
| unsigned isl_union_pw_aff_dim( |
| __isl_keep isl_union_pw_aff *upa, |
| enum isl_dim_type type); |
| unsigned isl_union_pw_multi_aff_dim( |
| __isl_keep isl_union_pw_multi_aff *upma, |
| enum isl_dim_type type); |
| unsigned isl_multi_union_pw_aff_dim( |
| __isl_keep isl_multi_union_pw_aff *mupa, |
| enum isl_dim_type type); |
| |
| #include <isl/polynomial.h> |
| unsigned isl_union_pw_qpolynomial_dim( |
| __isl_keep isl_union_pw_qpolynomial *upwqp, |
| enum isl_dim_type type); |
| unsigned isl_union_pw_qpolynomial_fold_dim( |
| __isl_keep isl_union_pw_qpolynomial_fold *upwf, |
| enum isl_dim_type type); |
| |
| Note that an C<isl_union_set>, an C<isl_union_map>, |
| an C<isl_union_pw_multi_aff>, |
| an C<isl_union_pw_qpolynomial> and |
| an C<isl_union_pw_qpolynomial_fold> |
| only have parameters. |
| |
| Additional parameters can be added to a space using the following function. |
| |
| #include <isl/space.h> |
| __isl_give isl_space *isl_space_add_param_id( |
| __isl_take isl_space *space, |
| __isl_take isl_id *id); |
| |
| If a parameter with the given identifier already appears in the space, |
| then it is not added again. |
| |
| The identifiers or names of the individual dimensions of spaces |
| may be set or read off using the following functions on spaces |
| or objects that live in spaces. |
| These functions are mostly useful to obtain the identifiers, positions |
| or names of the parameters. Identifiers of individual dimensions are |
| essentially only useful for printing. They are ignored by all other |
| operations and may not be preserved across those operations. |
| |
| #include <isl/space.h> |
| __isl_give isl_space *isl_space_set_dim_id( |
| __isl_take isl_space *space, |
| enum isl_dim_type type, unsigned pos, |
| __isl_take isl_id *id); |
| isl_bool isl_space_has_dim_id(__isl_keep isl_space *space, |
| enum isl_dim_type type, unsigned pos); |
| __isl_give isl_id *isl_space_get_dim_id( |
| __isl_keep isl_space *space, |
| enum isl_dim_type type, unsigned pos); |
| __isl_give isl_space *isl_space_set_dim_name( |
| __isl_take isl_space *space, |
| enum isl_dim_type type, unsigned pos, |
| __isl_keep const char *name); |
| isl_bool isl_space_has_dim_name(__isl_keep isl_space *space, |
| enum isl_dim_type type, unsigned pos); |
| __isl_keep const char *isl_space_get_dim_name( |
| __isl_keep isl_space *space, |
| enum isl_dim_type type, unsigned pos); |
| |
| #include <isl/local_space.h> |
| __isl_give isl_local_space *isl_local_space_set_dim_id( |
| __isl_take isl_local_space *ls, |
| enum isl_dim_type type, unsigned pos, |
| __isl_take isl_id *id); |
| isl_bool 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); |
| __isl_give isl_local_space *isl_local_space_set_dim_name( |
| __isl_take isl_local_space *ls, |
| enum isl_dim_type type, unsigned pos, const char *s); |
| isl_bool isl_local_space_has_dim_name( |
| __isl_keep isl_local_space *ls, |
| enum isl_dim_type type, unsigned pos) |
| const char *isl_local_space_get_dim_name( |
| __isl_keep isl_local_space *ls, |
| enum isl_dim_type type, unsigned pos); |
| |
| #include <isl/constraint.h> |
| const char *isl_constraint_get_dim_name( |
| __isl_keep isl_constraint *constraint, |
| enum isl_dim_type type, unsigned pos); |
| |
| #include <isl/set.h> |
| __isl_give isl_id *isl_basic_set_get_dim_id( |
| __isl_keep isl_basic_set *bset, |
| enum isl_dim_type type, unsigned pos); |
| __isl_give isl_set *isl_set_set_dim_id( |
| __isl_take isl_set *set, enum isl_dim_type type, |
| unsigned pos, __isl_take isl_id *id); |
| isl_bool isl_set_has_dim_id(__isl_keep isl_set *set, |
| enum isl_dim_type type, unsigned pos); |
| __isl_give isl_id *isl_set_get_dim_id( |
| __isl_keep isl_set *set, enum isl_dim_type type, |
| unsigned pos); |
| const char *isl_basic_set_get_dim_name( |
| __isl_keep isl_basic_set *bset, |
| enum isl_dim_type type, unsigned pos); |
| isl_bool isl_set_has_dim_name(__isl_keep isl_set *set, |
| enum isl_dim_type type, unsigned pos); |
| const char *isl_set_get_dim_name( |
| __isl_keep isl_set *set, |
| enum isl_dim_type type, unsigned pos); |
| |
| #include <isl/map.h> |
| __isl_give isl_map *isl_map_set_dim_id( |
| __isl_take isl_map *map, enum isl_dim_type type, |
| unsigned pos, __isl_take isl_id *id); |
| isl_bool isl_basic_map_has_dim_id( |
| __isl_keep isl_basic_map *bmap, |
| enum isl_dim_type type, unsigned pos); |
| isl_bool isl_map_has_dim_id(__isl_keep isl_map *map, |
| enum isl_dim_type type, unsigned pos); |
| __isl_give isl_id *isl_map_get_dim_id( |
| __isl_keep isl_map *map, enum isl_dim_type type, |
| unsigned pos); |
| __isl_give isl_id *isl_union_map_get_dim_id( |
| __isl_keep isl_union_map *umap, |
| enum isl_dim_type type, unsigned pos); |
| const char *isl_basic_map_get_dim_name( |
| __isl_keep isl_basic_map *bmap, |
| enum isl_dim_type type, unsigned pos); |
| isl_bool 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); |
| |
| #include <isl/val.h> |
| __isl_give isl_multi_val *isl_multi_val_set_dim_id( |
| __isl_take isl_multi_val *mv, |
| enum isl_dim_type type, unsigned pos, |
| __isl_take isl_id *id); |
| __isl_give isl_id *isl_multi_val_get_dim_id( |
| __isl_keep isl_multi_val *mv, |
| enum isl_dim_type type, unsigned pos); |
| __isl_give isl_multi_val *isl_multi_val_set_dim_name( |
| __isl_take isl_multi_val *mv, |
| enum isl_dim_type type, unsigned pos, const char *s); |
| |
| #include <isl/aff.h> |
| __isl_give isl_aff *isl_aff_set_dim_id( |
| __isl_take isl_aff *aff, enum isl_dim_type type, |
| unsigned pos, __isl_take isl_id *id); |
| __isl_give isl_multi_aff *isl_multi_aff_set_dim_id( |
| __isl_take isl_multi_aff *maff, |
| enum isl_dim_type type, unsigned pos, |
| __isl_take isl_id *id); |
| __isl_give isl_pw_aff *isl_pw_aff_set_dim_id( |
| __isl_take isl_pw_aff *pma, |
| enum isl_dim_type type, unsigned pos, |
| __isl_take isl_id *id); |
| __isl_give isl_multi_pw_aff * |
| isl_multi_pw_aff_set_dim_id( |
| __isl_take isl_multi_pw_aff *mpa, |
| enum isl_dim_type type, unsigned pos, |
| __isl_take isl_id *id); |
| __isl_give isl_multi_union_pw_aff * |
| isl_multi_union_pw_aff_set_dim_id( |
| __isl_take isl_multi_union_pw_aff *mupa, |
| enum isl_dim_type type, unsigned pos, |
| __isl_take isl_id *id); |
| __isl_give isl_id *isl_multi_aff_get_dim_id( |
| __isl_keep isl_multi_aff *ma, |
| enum isl_dim_type type, unsigned pos); |
| isl_bool isl_pw_aff_has_dim_id(__isl_keep isl_pw_aff *pa, |
| enum isl_dim_type type, unsigned pos); |
| __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_multi_aff_get_dim_id( |
| __isl_keep isl_pw_multi_aff *pma, |
| enum isl_dim_type type, unsigned pos); |
| __isl_give isl_id *isl_multi_pw_aff_get_dim_id( |
| __isl_keep isl_multi_pw_aff *mpa, |
| enum isl_dim_type type, unsigned pos); |
| __isl_give isl_id *isl_multi_union_pw_aff_get_dim_id( |
| __isl_keep isl_multi_union_pw_aff *mupa, |
| enum isl_dim_type type, unsigned pos); |
| __isl_give isl_aff *isl_aff_set_dim_name( |
| __isl_take isl_aff *aff, enum isl_dim_type type, |
| unsigned pos, const char *s); |
| __isl_give isl_multi_aff *isl_multi_aff_set_dim_name( |
| __isl_take isl_multi_aff *maff, |
| enum isl_dim_type type, unsigned pos, const char *s); |
| __isl_give isl_multi_pw_aff * |
| isl_multi_pw_aff_set_dim_name( |
| __isl_take isl_multi_pw_aff *mpa, |
| enum isl_dim_type type, unsigned pos, const char *s); |
| __isl_give isl_union_pw_aff * |
| isl_union_pw_aff_set_dim_name( |
| __isl_take isl_union_pw_aff *upa, |
| enum isl_dim_type type, unsigned pos, |
| const char *s); |
| __isl_give isl_union_pw_multi_aff * |
| isl_union_pw_multi_aff_set_dim_name( |
| __isl_take isl_union_pw_multi_aff *upma, |
| enum isl_dim_type type, unsigned pos, |
| const char *s); |
| __isl_give isl_multi_union_pw_aff * |
| isl_multi_union_pw_aff_set_dim_name( |
| __isl_take isl_multi_union_pw_aff *mupa, |
| enum isl_dim_type type, unsigned pos, |
| const char *isl_aff_get_dim_name(__isl_keep isl_aff *aff, |
| enum isl_dim_type type, unsigned pos); |
| const char *isl_pw_aff_get_dim_name( |
| __isl_keep isl_pw_aff *pa, |
| enum isl_dim_type type, unsigned pos); |
| const char *isl_pw_multi_aff_get_dim_name( |
| __isl_keep isl_pw_multi_aff *pma, |
| enum isl_dim_type type, unsigned pos); |
| |
| #include <isl/polynomial.h> |
| __isl_give isl_qpolynomial *isl_qpolynomial_set_dim_name( |
| __isl_take isl_qpolynomial *qp, |
| enum isl_dim_type type, unsigned pos, |
| const char *s); |
| __isl_give isl_pw_qpolynomial * |
| isl_pw_qpolynomial_set_dim_name( |
| __isl_take isl_pw_qpolynomial *pwqp, |
| enum isl_dim_type type, unsigned pos, |
| const char *s); |
| __isl_give isl_pw_qpolynomial_fold * |
| isl_pw_qpolynomial_fold_set_dim_name( |
| __isl_take isl_pw_qpolynomial_fold *pwf, |
| enum isl_dim_type type, unsigned pos, |
| const char *s); |
| __isl_give isl_union_pw_qpolynomial * |
| isl_union_pw_qpolynomial_set_dim_name( |
| __isl_take isl_union_pw_qpolynomial *upwqp, |
| enum isl_dim_type type, unsigned pos, |
| const char *s); |
| __isl_give isl_union_pw_qpolynomial_fold * |
| isl_union_pw_qpolynomial_fold_set_dim_name( |
| __isl_take isl_union_pw_qpolynomial_fold *upwf, |
| enum isl_dim_type type, unsigned pos, |
| const char *s); |
| |
| Note that C<isl_space_get_name> returns a pointer to some internal |
| data structure, so the result can only be used while the |
| corresponding C<isl_space> is alive. |
| Also note that every function that operates on two sets or relations |
| requires that both arguments have the same parameters. This also |
| means that if one of the arguments has named parameters, then the |
| other needs to have named parameters too and the names need to match. |
| Pairs of C<isl_set>, C<isl_map>, C<isl_union_set> and/or C<isl_union_map> |
| arguments may have different parameters (as long as they are named), |
| in which case the result will have as parameters the union of the parameters of |
| the arguments. |
| |
| Given the identifier or name of a dimension (typically a parameter), |
| its position can be obtained from the following functions. |
| |
| #include <isl/space.h> |
| int isl_space_find_dim_by_id(__isl_keep isl_space *space, |
| enum isl_dim_type type, __isl_keep isl_id *id); |
| int isl_space_find_dim_by_name(__isl_keep isl_space *space, |
| enum isl_dim_type type, const char *name); |
| |
| #include <isl/local_space.h> |
| int isl_local_space_find_dim_by_name( |
| __isl_keep isl_local_space *ls, |
| enum isl_dim_type type, const char *name); |
| |
| #include <isl/val.h> |
| int isl_multi_val_find_dim_by_id( |
| __isl_keep isl_multi_val *mv, |
| enum isl_dim_type type, __isl_keep isl_id *id); |
| int isl_multi_val_find_dim_by_name( |
| __isl_keep isl_multi_val *mv, |
| enum isl_dim_type type, const char *name); |
| |
| #include <isl/set.h> |
| int isl_set_find_dim_by_id(__isl_keep isl_set *set, |
| enum isl_dim_type type, __isl_keep isl_id *id); |
| int isl_set_find_dim_by_name(__isl_keep isl_set *set, |
| enum isl_dim_type type, const char *name); |
| |
| #include <isl/map.h> |
| int isl_map_find_dim_by_id(__isl_keep isl_map *map, |
| enum isl_dim_type type, __isl_keep isl_id *id); |
| int isl_basic_map_find_dim_by_name( |
| __isl_keep isl_basic_map *bmap, |
| enum isl_dim_type type, const char *name); |
| int isl_map_find_dim_by_name(__isl_keep isl_map *map, |
| enum isl_dim_type type, const char *name); |
| int isl_union_map_find_dim_by_name( |
| __isl_keep isl_union_map *umap, |
| enum isl_dim_type type, const char *name); |
| |
| #include <isl/aff.h> |
| int isl_multi_aff_find_dim_by_id( |
| __isl_keep isl_multi_aff *ma, |
| enum isl_dim_type type, __isl_keep isl_id *id); |
| int isl_multi_pw_aff_find_dim_by_id( |
| __isl_keep isl_multi_pw_aff *mpa, |
| enum isl_dim_type type, __isl_keep isl_id *id); |
| int isl_multi_union_pw_aff_find_dim_by_id( |
| __isl_keep isl_union_multi_pw_aff *mupa, |
| enum isl_dim_type type, __isl_keep isl_id *id); |
| int isl_aff_find_dim_by_name(__isl_keep isl_aff *aff, |
| enum isl_dim_type type, const char *name); |
| int isl_multi_aff_find_dim_by_name( |
| __isl_keep isl_multi_aff *ma, |
| enum isl_dim_type type, const char *name); |
| int isl_pw_aff_find_dim_by_name(__isl_keep isl_pw_aff *pa, |
| enum isl_dim_type type, const char *name); |
| int isl_multi_pw_aff_find_dim_by_name( |
| __isl_keep isl_multi_pw_aff *mpa, |
| enum isl_dim_type type, const char *name); |
| int isl_pw_multi_aff_find_dim_by_name( |
| __isl_keep isl_pw_multi_aff *pma, |
| enum isl_dim_type type, const char *name); |
| int isl_union_pw_aff_find_dim_by_name( |
| __isl_keep isl_union_pw_aff *upa, |
| enum isl_dim_type type, const char *name); |
| int isl_union_pw_multi_aff_find_dim_by_name( |
| __isl_keep isl_union_pw_multi_aff *upma, |
| enum isl_dim_type type, const char *name); |
| int isl_multi_union_pw_aff_find_dim_by_name( |
| __isl_keep isl_multi_union_pw_aff *mupa, |
| enum isl_dim_type type, const char *name); |
| |
| #include <isl/polynomial.h> |
| int isl_pw_qpolynomial_find_dim_by_name( |
| __isl_keep isl_pw_qpolynomial *pwqp, |
| enum isl_dim_type type, const char *name); |
| int isl_pw_qpolynomial_fold_find_dim_by_name( |
| __isl_keep isl_pw_qpolynomial_fold *pwf, |
| enum isl_dim_type type, const char *name); |
| int isl_union_pw_qpolynomial_find_dim_by_name( |
| __isl_keep isl_union_pw_qpolynomial *upwqp, |
| enum isl_dim_type type, const char *name); |
| int isl_union_pw_qpolynomial_fold_find_dim_by_name( |
| __isl_keep isl_union_pw_qpolynomial_fold *upwf, |
| enum isl_dim_type type, const char *name); |
| |
| The identifiers or names of entire spaces may be set or read off |
| using the following functions. |
| |
| #include <isl/space.h> |
| __isl_give isl_space *isl_space_set_tuple_id( |
| __isl_take isl_space *space, |
| enum isl_dim_type type, __isl_take isl_id *id); |
| __isl_give isl_space *isl_space_reset_tuple_id( |
| __isl_take isl_space *space, enum isl_dim_type type); |
| isl_bool isl_space_has_tuple_id( |
| __isl_keep isl_space *space, |
| enum isl_dim_type type); |
| __isl_give isl_id *isl_space_get_tuple_id( |
| __isl_keep isl_space *space, enum isl_dim_type type); |
| __isl_give isl_space *isl_space_set_tuple_name( |
| __isl_take isl_space *space, |
| enum isl_dim_type type, const char *s); |
| isl_bool isl_space_has_tuple_name( |
| __isl_keep isl_space *space, |
| enum isl_dim_type type); |
| __isl_keep const char *isl_space_get_tuple_name( |
| __isl_keep isl_space *space, |
| enum isl_dim_type type); |
| |
| #include <isl/local_space.h> |
| __isl_give isl_local_space *isl_local_space_set_tuple_id( |
| __isl_take isl_local_space *ls, |
| enum isl_dim_type type, __isl_take isl_id *id); |
| |
| #include <isl/set.h> |
| __isl_give isl_basic_set *isl_basic_set_set_tuple_id( |
| __isl_take isl_basic_set *bset, |
| __isl_take isl_id *id); |
| __isl_give isl_set *isl_set_set_tuple_id( |
| __isl_take isl_set *set, __isl_take isl_id *id); |
| __isl_give isl_set *isl_set_reset_tuple_id( |
| __isl_take isl_set *set); |
| isl_bool isl_set_has_tuple_id(__isl_keep isl_set *set); |
| __isl_give isl_id *isl_set_get_tuple_id( |
| __isl_keep isl_set *set); |
| __isl_give isl_basic_set *isl_basic_set_set_tuple_name( |
| __isl_take isl_basic_set *set, const char *s); |
| __isl_give isl_set *isl_set_set_tuple_name( |
| __isl_take isl_set *set, const char *s); |
| const char *isl_basic_set_get_tuple_name( |
| __isl_keep isl_basic_set *bset); |
| isl_bool isl_set_has_tuple_name(__isl_keep isl_set *set); |
| const char *isl_set_get_tuple_name( |
| __isl_keep isl_set *set); |
| |
| #include <isl/map.h> |
| __isl_give isl_basic_map *isl_basic_map_set_tuple_id( |
| __isl_take isl_basic_map *bmap, |
| enum isl_dim_type type, __isl_take isl_id *id); |
| __isl_give isl_map *isl_map_set_tuple_id( |
| __isl_take isl_map *map, enum isl_dim_type type, |
| __isl_take isl_id *id); |
| __isl_give isl_map *isl_map_reset_tuple_id( |
| __isl_take isl_map *map, enum isl_dim_type type); |
| isl_bool isl_map_has_tuple_id(__isl_keep isl_map *map, |
| enum isl_dim_type type); |
| __isl_give isl_id *isl_map_get_tuple_id( |
| __isl_keep isl_map *map, enum isl_dim_type type); |
| __isl_give isl_map *isl_map_set_tuple_name( |
| __isl_take isl_map *map, |
| enum isl_dim_type type, const char *s); |
| const char *isl_basic_map_get_tuple_name( |
| __isl_keep isl_basic_map *bmap, |
| enum isl_dim_type type); |
| __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); |
| isl_bool 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); |
| |
| #include <isl/val.h> |
| __isl_give isl_multi_val *isl_multi_val_set_tuple_id( |
| __isl_take isl_multi_val *mv, |
| enum isl_dim_type type, __isl_take isl_id *id); |
| __isl_give isl_multi_val *isl_multi_val_reset_tuple_id( |
| __isl_take isl_multi_val *mv, |
| enum isl_dim_type type); |
| isl_bool isl_multi_val_has_tuple_id( |
| __isl_keep isl_multi_val *mv, |
| enum isl_dim_type type); |
| __isl_give isl_id *isl_multi_val_get_tuple_id( |
| __isl_keep isl_multi_val *mv, |
| enum isl_dim_type type); |
| __isl_give isl_multi_val *isl_multi_val_set_tuple_name( |
| __isl_take isl_multi_val *mv, |
| enum isl_dim_type type, const char *s); |
| const char *isl_multi_val_get_tuple_name( |
| __isl_keep isl_multi_val *mv, |
| enum isl_dim_type type); |
| |
| #include <isl/aff.h> |
| __isl_give isl_aff *isl_aff_set_tuple_id( |
| __isl_take isl_aff *aff, |
| enum isl_dim_type type, __isl_take isl_id *id); |
| __isl_give isl_multi_aff *isl_multi_aff_set_tuple_id( |
| __isl_take isl_multi_aff *maff, |
| enum isl_dim_type type, __isl_take isl_id *id); |
| __isl_give isl_pw_aff *isl_pw_aff_set_tuple_id( |
| __isl_take isl_pw_aff *pwaff, |
| enum isl_dim_type type, __isl_take isl_id *id); |
| __isl_give isl_pw_multi_aff *isl_pw_multi_aff_set_tuple_id( |
| __isl_take isl_pw_multi_aff *pma, |
| enum isl_dim_type type, __isl_take isl_id *id); |
| __isl_give isl_multi_union_pw_aff * |
| isl_multi_union_pw_aff_set_tuple_id( |
| __isl_take isl_multi_union_pw_aff *mupa, |
| enum isl_dim_type type, __isl_take isl_id *id); |
| __isl_give isl_multi_aff *isl_multi_aff_reset_tuple_id( |
| __isl_take isl_multi_aff *ma, |
| enum isl_dim_type type); |
| __isl_give isl_pw_aff *isl_pw_aff_reset_tuple_id( |
| __isl_take isl_pw_aff *pa, |
| enum isl_dim_type type); |
| __isl_give isl_multi_pw_aff * |
| isl_multi_pw_aff_reset_tuple_id( |
| __isl_take isl_multi_pw_aff *mpa, |
| enum isl_dim_type type); |
| __isl_give isl_pw_multi_aff * |
| isl_pw_multi_aff_reset_tuple_id( |
| __isl_take isl_pw_multi_aff *pma, |
| enum isl_dim_type type); |
| __isl_give isl_multi_union_pw_aff * |
| isl_multi_union_pw_aff_reset_tuple_id( |
| __isl_take isl_multi_union_pw_aff *mupa, |
| enum isl_dim_type type); |
| isl_bool isl_multi_aff_has_tuple_id( |
| __isl_keep isl_multi_aff *ma, |
| enum isl_dim_type type); |
| __isl_give isl_id *isl_multi_aff_get_tuple_id( |
| __isl_keep isl_multi_aff *ma, |
| enum isl_dim_type type); |
| isl_bool isl_pw_aff_has_tuple_id(__isl_keep isl_pw_aff *pa, |
| enum isl_dim_type type); |
| __isl_give isl_id *isl_pw_aff_get_tuple_id( |
| __isl_keep isl_pw_aff *pa, |
| enum isl_dim_type type); |
| isl_bool isl_pw_multi_aff_has_tuple_id( |
| __isl_keep isl_pw_multi_aff *pma, |
| enum isl_dim_type type); |
| __isl_give isl_id *isl_pw_multi_aff_get_tuple_id( |
| __isl_keep isl_pw_multi_aff *pma, |
| enum isl_dim_type type); |
| isl_bool isl_multi_pw_aff_has_tuple_id( |
| __isl_keep isl_multi_pw_aff *mpa, |
| enum isl_dim_type type); |
| __isl_give isl_id *isl_multi_pw_aff_get_tuple_id( |
| __isl_keep isl_multi_pw_aff *mpa, |
| enum isl_dim_type type); |
| isl_bool isl_multi_union_pw_aff_has_tuple_id( |
| __isl_keep isl_multi_union_pw_aff *mupa, |
| enum isl_dim_type type); |
| __isl_give isl_id *isl_multi_union_pw_aff_get_tuple_id( |
| __isl_keep isl_multi_union_pw_aff *mupa, |
| enum isl_dim_type type); |
| __isl_give isl_multi_aff *isl_multi_aff_set_tuple_name( |
| __isl_take isl_multi_aff *maff, |
| enum isl_dim_type type, const char *s); |
| __isl_give isl_multi_pw_aff * |
| isl_multi_pw_aff_set_tuple_name( |
| __isl_take isl_multi_pw_aff *mpa, |
| enum isl_dim_type type, const char *s); |
| __isl_give isl_multi_union_pw_aff * |
| isl_multi_union_pw_aff_set_tuple_name( |
| __isl_take isl_multi_union_pw_aff *mupa, |
| enum isl_dim_type type, const char *s); |
| const char *isl_multi_aff_get_tuple_name( |
| __isl_keep isl_multi_aff *multi, |
| enum isl_dim_type type); |
| isl_bool 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); |
| const char *isl_multi_union_pw_aff_get_tuple_name( |
| __isl_keep isl_multi_union_pw_aff *mupa, |
| enum isl_dim_type type); |
| |
| The C<type> argument needs to be one of C<isl_dim_in>, C<isl_dim_out> |
| or C<isl_dim_set>. As with C<isl_space_get_name>, |
| the C<isl_space_get_tuple_name> function returns a pointer to some internal |
| data structure. |
| Binary operations require the corresponding spaces of their arguments |
| to have the same name. |
| |
| To keep the names of all parameters and tuples, but reset the user pointers |
| of all the corresponding identifiers, use the following function. |
| |
| #include <isl/space.h> |
| __isl_give isl_space *isl_space_reset_user( |
| __isl_take isl_space *space); |
| |
| #include <isl/set.h> |
| __isl_give isl_set *isl_set_reset_user( |
| __isl_take isl_set *set); |
| |
| #include <isl/map.h> |
| __isl_give isl_map *isl_map_reset_user( |
| __isl_take isl_map *map); |
| |
| #include <isl/union_set.h> |
| __isl_give isl_union_set *isl_union_set_reset_user( |
| __isl_take isl_union_set *uset); |
| |
| #include <isl/union_map.h> |
| __isl_give isl_union_map *isl_union_map_reset_user( |
| __isl_take isl_union_map *umap); |
| |
| #include <isl/val.h> |
| __isl_give isl_multi_val *isl_multi_val_reset_user( |
| __isl_take isl_multi_val *mv); |
| |
| #include <isl/aff.h> |
| __isl_give isl_multi_aff *isl_multi_aff_reset_user( |
| __isl_take isl_multi_aff *ma); |
| __isl_give isl_pw_aff *isl_pw_aff_reset_user( |
| __isl_take isl_pw_aff *pa); |
| __isl_give isl_multi_pw_aff *isl_multi_pw_aff_reset_user( |
| __isl_take isl_multi_pw_aff *mpa); |
| __isl_give isl_pw_multi_aff *isl_pw_multi_aff_reset_user( |
| __isl_take isl_pw_multi_aff *pma); |
| __isl_give isl_union_pw_aff *isl_union_pw_aff_reset_user( |
| __isl_take isl_union_pw_aff *upa); |
| __isl_give isl_multi_union_pw_aff * |
| isl_multi_union_pw_aff_reset_user( |
| __isl_take isl_multi_union_pw_aff *mupa); |
| __isl_give isl_union_pw_multi_aff * |
| isl_union_pw_multi_aff_reset_user( |
| __isl_take isl_union_pw_multi_aff *upma); |
| |
| #include <isl/polynomial.h> |
| __isl_give isl_pw_qpolynomial * |
| isl_pw_qpolynomial_reset_user( |
| __isl_take isl_pw_qpolynomial *pwqp); |
| __isl_give isl_union_pw_qpolynomial * |
| isl_union_pw_qpolynomial_reset_user( |
| __isl_take isl_union_pw_qpolynomial *upwqp); |
| __isl_give isl_pw_qpolynomial_fold * |
| isl_pw_qpolynomial_fold_reset_user( |
| __isl_take isl_pw_qpolynomial_fold *pwf); |
| __isl_give isl_union_pw_qpolynomial_fold * |
| isl_union_pw_qpolynomial_fold_reset_user( |
| __isl_take isl_union_pw_qpolynomial_fold *upwf); |
| |
| Spaces can be nested. In particular, the domain of a set or |
| the domain or range of a relation can be a nested relation. |
| This process is also called I<wrapping>. |
| The functions for detecting, constructing and deconstructing |
| such nested spaces can be found in the wrapping properties |
| of L</"Unary Properties">, the wrapping operations |
| of L</"Unary Operations"> and the Cartesian product operations |
| of L</"Basic Operations">. |
| |
| Spaces can be created from other spaces |
| using the functions described in L</"Unary Operations"> |
| and L</"Binary Operations">. |
| |
| =head2 Local Spaces |
| |
| A local space is essentially a space with |
| zero or more existentially quantified variables. |
| The local space of various objects can be obtained |
| using the following functions. |
| |
| #include <isl/constraint.h> |
| __isl_give isl_local_space *isl_constraint_get_local_space( |
| __isl_keep isl_constraint *constraint); |
| |
| #include <isl/set.h> |
| __isl_give isl_local_space *isl_basic_set_get_local_space( |
| __isl_keep isl_basic_set *bset); |
| |
| #include <isl/map.h> |
| __isl_give isl_local_space *isl_basic_map_get_local_space( |
| __isl_keep isl_basic_map *bmap); |
| |
| #include <isl/aff.h> |
| __isl_give isl_local_space *isl_aff_get_domain_local_space( |
| __isl_keep isl_aff *aff); |
| __isl_give isl_local_space *isl_aff_get_local_space( |
| __isl_keep isl_aff *aff); |
| |
| A new local space can be created from a space using |
| |
| #include <isl/local_space.h> |
| __isl_give isl_local_space *isl_local_space_from_space( |
| __isl_take isl_space *space); |
| |
| They can be inspected, modified, copied and freed using the following functions. |
| |
| #include <isl/local_space.h> |
| isl_bool isl_local_space_is_params( |
| __isl_keep isl_local_space *ls); |
| isl_bool isl_local_space_is_set( |
| __isl_keep isl_local_space *ls); |
| __isl_give isl_space *isl_local_space_get_space( |
| __isl_keep isl_local_space *ls); |
| __isl_give isl_aff *isl_local_space_get_div( |
| __isl_keep isl_local_space *ls, int pos); |
| __isl_give isl_local_space *isl_local_space_copy( |
| __isl_keep isl_local_space *ls); |
| __isl_null isl_local_space *isl_local_space_free( |
| __isl_take isl_local_space *ls); |
| |
| Note that C<isl_local_space_get_div> can only be used on local spaces |
| of sets. |
| |
| Two local spaces can be compared using |
| |
| isl_bool isl_local_space_is_equal( |
| __isl_keep isl_local_space *ls1, |
| __isl_keep isl_local_space *ls2); |
| |
| Local spaces can be created from other local spaces |
| using the functions described in L</"Unary Operations"> |
| and L</"Binary Operations">. |
| |
| =head2 Creating New Sets and Relations |
| |
| C<isl> has functions for creating some standard sets and relations. |
| |
| =over |
| |
| =item * Empty sets and relations |
| |
| __isl_give isl_basic_set *isl_basic_set_empty( |
| __isl_take isl_space *space); |
| __isl_give isl_basic_map *isl_basic_map_empty( |
| __isl_take isl_space *space); |
| __isl_give isl_set *isl_set_empty( |
| __isl_take isl_space *space); |
| __isl_give isl_map *isl_map_empty( |
| __isl_take isl_space *space); |
| __isl_give isl_union_set *isl_union_set_empty( |
| __isl_take isl_space *space); |
| __isl_give isl_union_map *isl_union_map_empty( |
| __isl_take isl_space *space); |
| |
| For C<isl_union_set>s and C<isl_union_map>s, the space |
| is only used to specify the parameters. |
| |
| =item * Universe sets and relations |
| |
| __isl_give isl_basic_set *isl_basic_set_universe( |
| __isl_take isl_space *space); |
| __isl_give isl_basic_map *isl_basic_map_universe( |
| __isl_take isl_space *space); |
| __isl_give isl_set *isl_set_universe( |
| __isl_take isl_space *space); |
| __isl_give isl_map *isl_map_universe( |
| __isl_take isl_space *space); |
| __isl_give isl_union_set *isl_union_set_universe( |
| __isl_take isl_union_set *uset); |
| __isl_give isl_union_map *isl_union_map_universe( |
| __isl_take isl_union_map *umap); |
| |
| The sets and relations constructed by the functions above |
| contain all integer values, while those constructed by the |
| functions below only contain non-negative values. |
| |
| __isl_give isl_basic_set *isl_basic_set_nat_universe( |
| __isl_take isl_space *space); |
| __isl_give isl_basic_map *isl_basic_map_nat_universe( |
| __isl_take isl_space *space); |
| __isl_give isl_set *isl_set_nat_universe( |
| __isl_take isl_space *space); |
| __isl_give isl_map *isl_map_nat_universe( |
| __isl_take isl_space *space); |
| |
| =item * Identity relations |
| |
| __isl_give isl_basic_map *isl_basic_map_identity( |
| __isl_take isl_space *space); |
| __isl_give isl_map *isl_map_identity( |
| __isl_take isl_space *space); |
| |
| The number of input and output dimensions in C<space> needs |
| to be the same. |
| |
| =item * Lexicographic order |
| |
| __isl_give isl_map *isl_map_lex_lt( |
| __isl_take isl_space *set_space); |
| __isl_give isl_map *isl_map_lex_le( |
| __isl_take isl_space *set_space); |
| __isl_give isl_map *isl_map_lex_gt( |
| __isl_take isl_space *set_space); |
| __isl_give isl_map *isl_map_lex_ge( |
| __isl_take isl_space *set_space); |
| __isl_give isl_map *isl_map_lex_lt_first( |
| __isl_take isl_space *space, unsigned n); |
| __isl_give isl_map *isl_map_lex_le_first( |
| __isl_take isl_space *space, unsigned n); |
| __isl_give isl_map *isl_map_lex_gt_first( |
| __isl_take isl_space *space, unsigned n); |
| __isl_give isl_map *isl_map_lex_ge_first( |
| __isl_take isl_space *space, unsigned n); |
| |
| The first four functions take a space for a B<set> |
| and return relations that express that the elements in the domain |
| are lexicographically less |
| (C<isl_map_lex_lt>), less or equal (C<isl_map_lex_le>), |
| greater (C<isl_map_lex_gt>) or greater or equal (C<isl_map_lex_ge>) |
| than the elements in the range. |
| The last four functions take a space for a map |
| and return relations that express that the first C<n> dimensions |
| in the domain are lexicographically less |
| (C<isl_map_lex_lt_first>), less or equal (C<isl_map_lex_le_first>), |
| greater (C<isl_map_lex_gt_first>) or greater or equal (C<isl_map_lex_ge_first>) |
| than the first C<n> dimensions in the range. |
| |
| =back |
| |
| A basic set or relation can be converted to a set or relation |
| using the following functions. |
| |
| __isl_give isl_set *isl_set_from_basic_set( |
| __isl_take isl_basic_set *bset); |
| __isl_give isl_map *isl_map_from_basic_map( |
| __isl_take isl_basic_map *bmap); |
| |
| Sets and relations can be converted to union sets and relations |
| using the following functions. |
| |
| __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 |
| space. |
| |
| __isl_give isl_set *isl_set_from_union_set( |
| __isl_take isl_union_set *uset); |
| __isl_give isl_map *isl_map_from_union_map( |
| __isl_take isl_union_map *umap); |
| |
| Sets and relations can be copied and freed again using the following |
| functions. |
| |
| __isl_give isl_basic_set *isl_basic_set_copy( |
| __isl_keep isl_basic_set *bset); |
| __isl_give isl_set *isl_set_copy(__isl_keep isl_set *set); |
| __isl_give isl_union_set *isl_union_set_copy( |
| __isl_keep isl_union_set *uset); |
| __isl_give isl_basic_map *isl_basic_map_copy( |
| __isl_keep isl_basic_map *bmap); |
| __isl_give isl_map *isl_map_copy(__isl_keep isl_map *map); |
| __isl_give isl_union_map *isl_union_map_copy( |
| __isl_keep isl_union_map *umap); |
| __isl_null isl_basic_set *isl_basic_set_free( |
| __isl_take isl_basic_set *bset); |
| __isl_null isl_set *isl_set_free(__isl_take isl_set *set); |
| __isl_null isl_union_set *isl_union_set_free( |
| __isl_take isl_union_set *uset); |
| __isl_null isl_basic_map *isl_basic_map_free( |
| __isl_take isl_basic_map *bmap); |
| __isl_null isl_map *isl_map_free(__isl_take isl_map *map); |
| __isl_null isl_union_map *isl_union_map_free( |
| __isl_take isl_union_map *umap); |
| |
| Other sets and relations can be constructed by starting |
| from a universe set or relation, adding equality and/or |
| inequality constraints and then projecting out the |
| existentially quantified variables, if any. |
| Constraints can be constructed, manipulated and |
| added to (or removed from) (basic) sets and relations |
| using the following functions. |
| |
| #include <isl/constraint.h> |
| __isl_give isl_constraint *isl_constraint_alloc_equality( |
| __isl_take isl_local_space *ls); |
| __isl_give isl_constraint *isl_constraint_alloc_inequality( |
| __isl_take isl_local_space *ls); |
| __isl_give isl_constraint *isl_constraint_set_constant_si( |
| __isl_take isl_constraint *constraint, int v); |
| __isl_give isl_constraint *isl_constraint_set_constant_val( |
| __isl_take isl_constraint *constraint, |
| __isl_take isl_val *v); |
| __isl_give isl_constraint *isl_constraint_set_coefficient_si( |
| __isl_take isl_constraint *constraint, |
| enum isl_dim_type type, int pos, int v); |
| __isl_give isl_constraint * |
| isl_constraint_set_coefficient_val( |
| __isl_take isl_constraint *constraint, |
| enum isl_dim_type type, int pos, |
| __isl_take isl_val *v); |
| __isl_give isl_basic_map *isl_basic_map_add_constraint( |
| __isl_take isl_basic_map *bmap, |
| __isl_take isl_constraint *constraint); |
| __isl_give isl_basic_set *isl_basic_set_add_constraint( |
| __isl_take isl_basic_set *bset, |
| __isl_take isl_constraint *constraint); |
| __isl_give isl_map *isl_map_add_constraint( |
| __isl_take isl_map *map, |
| __isl_take isl_constraint *constraint); |
| __isl_give isl_set *isl_set_add_constraint( |
| __isl_take isl_set *set, |
| __isl_take isl_constraint *constraint); |
| |
| For example, to create a set containing the even integers |
| between 10 and 42, you would use the following code. |
| |
| isl_space *space; |
| isl_local_space *ls; |
| isl_constraint *c; |
| isl_basic_set *bset; |
| |
| space = isl_space_set_alloc(ctx, 0, 2); |
| bset = isl_basic_set_universe(isl_space_copy(space)); |
| ls = isl_local_space_from_space(space); |
| |
| c = isl_constraint_alloc_equality(isl_local_space_copy(ls)); |
| c = isl_constraint_set_coefficient_si(c, isl_dim_set, 0, -1); |
| c = isl_constraint_set_coefficient_si(c, isl_dim_set, 1, 2); |
| bset = isl_basic_set_add_constraint(bset, c); |
| |
| c = isl_constraint_alloc_inequality(isl_local_space_copy(ls)); |
| c = isl_constraint_set_constant_si(c, -10); |
| c = isl_constraint_set_coefficient_si(c, isl_dim_set, 0, 1); |
| bset = isl_basic_set_add_constraint(bset, c); |
| |
| c = isl_constraint_alloc_inequality(ls); |
| c = isl_constraint_set_constant_si(c, 42); |
| c = isl_constraint_set_coefficient_si(c, isl_dim_set, 0, -1); |
| bset = isl_basic_set_add_constraint(bset, c); |
| |
| bset = isl_basic_set_project_out(bset, isl_dim_set, 1, 1); |
| |
| Or, alternatively, |
| |
| isl_basic_set *bset; |
| bset = isl_basic_set_read_from_str(ctx, |
| "{[i] : exists (a : i = 2a and i >= 10 and i <= 42)}"); |
| |
| A basic set or relation can also be constructed from two matrices |
| describing the equalities and the inequalities. |
| |
| __isl_give isl_basic_set *isl_basic_set_from_constraint_matrices( |
| __isl_take isl_space *space, |
| __isl_take isl_mat *eq, __isl_take isl_mat *ineq, |
| enum isl_dim_type c1, |
| enum isl_dim_type c2, enum isl_dim_type c3, |
| enum isl_dim_type c4); |
| __isl_give isl_basic_map *isl_basic_map_from_constraint_matrices( |
| __isl_take isl_space *space, |
| __isl_take isl_mat *eq, __isl_take isl_mat *ineq, |
| enum isl_dim_type c1, |
| enum isl_dim_type c2, enum isl_dim_type c3, |
| enum isl_dim_type c4, enum isl_dim_type c5); |
| |
| The C<isl_dim_type> arguments indicate the order in which |
| different kinds of variables appear in the input matrices |
| and should be a permutation of C<isl_dim_cst>, C<isl_dim_param>, |
| C<isl_dim_set> and C<isl_dim_div> for sets and |
| of C<isl_dim_cst>, C<isl_dim_param>, |
| C<isl_dim_in>, C<isl_dim_out> and C<isl_dim_div> for relations. |
| |
| A (basic or union) set or relation can also be constructed from a |
| (union) (piecewise) (multiple) affine expression |
| or a list of affine expressions |
| (See L</"Functions">), provided these affine expressions do not |
| involve any NaN. |
| |
| #include <isl/set.h> |
| __isl_give isl_basic_set *isl_basic_set_from_multi_aff( |
| __isl_take isl_multi_aff *ma); |
| __isl_give isl_set *isl_set_from_multi_aff( |
| __isl_take isl_multi_aff *ma); |
| |
| #include <isl/map.h> |
| __isl_give isl_basic_map *isl_basic_map_from_aff( |
| __isl_take isl_aff *aff); |
| __isl_give isl_map *isl_map_from_aff( |
| __isl_take isl_aff *aff); |
| __isl_give isl_basic_map *isl_basic_map_from_aff_list( |
| __isl_take isl_space *domain_space, |
| __isl_take isl_aff_list *list); |
| __isl_give isl_basic_map *isl_basic_map_from_multi_aff( |
| __isl_take isl_multi_aff *maff) |
| __isl_give isl_map *isl_map_from_multi_aff( |
| __isl_take isl_multi_aff *maff) |
| |
| #include <isl/aff.h> |
| __isl_give isl_set *isl_set_from_pw_aff( |
| __isl_take isl_pw_aff *pwaff); |
| __isl_give isl_map *isl_map_from_pw_aff( |
| __isl_take isl_pw_aff *pwaff); |
| __isl_give isl_set *isl_set_from_pw_multi_aff( |
| __isl_take isl_pw_multi_aff *pma); |
| __isl_give isl_map *isl_map_from_pw_multi_aff( |
| __isl_take isl_pw_multi_aff *pma); |
| __isl_give isl_set *isl_set_from_multi_pw_aff( |
| __isl_take isl_multi_pw_aff *mpa); |
| __isl_give isl_map *isl_map_from_multi_pw_aff( |
| __isl_take isl_multi_pw_aff *mpa); |
| __isl_give isl_union_map *isl_union_map_from_union_pw_aff( |
| __isl_take isl_union_pw_aff *upa); |
| __isl_give isl_union_map * |
| isl_union_map_from_union_pw_multi_aff( |
| __isl_take isl_union_pw_multi_aff *upma); |
| __isl_give isl_union_map * |
| isl_union_map_from_multi_union_pw_aff( |
| __isl_take isl_multi_union_pw_aff *mupa); |
| |
| The C<domain_space> argument describes the domain of the resulting |
| basic relation. It is required because the C<list> may consist |
| of zero affine expressions. |
| The C<mupa> passed to C<isl_union_map_from_multi_union_pw_aff> |
| is not allowed to be zero-dimensional. The domain of the result |
| is the shared domain of the union piecewise affine elements. |
| |
| =head2 Inspecting Sets and Relations |
| |
| Usually, the user should not have to care about the actual constraints |
| of the sets and maps, but should instead apply the abstract operations |
| explained in the following sections. |
| Occasionally, however, it may be required to inspect the individual |
| coefficients of the constraints. This section explains how to do so. |
| In these cases, it may also be useful to have C<isl> compute |
| an explicit representation of the existentially quantified variables. |
| |
| __isl_give isl_set *isl_set_compute_divs( |
| __isl_take isl_set *set); |
| __isl_give isl_map *isl_map_compute_divs( |
| __isl_take isl_map *map); |
| __isl_give isl_union_set *isl_union_set_compute_divs( |
| __isl_take isl_union_set *uset); |
| __isl_give isl_union_map *isl_union_map_compute_divs( |
| __isl_take isl_union_map *umap); |
| |
| This explicit representation defines the existentially quantified |
| variables as integer divisions of the other variables, possibly |
| including earlier existentially quantified variables. |
| An explicitly represented existentially quantified variable therefore |
| has a unique value when the values of the other variables are known. |
| |
| Alternatively, the existentially quantified variables can be removed |
| using the following functions, which compute an overapproximation. |
| |
| #include <isl/set.h> |
| __isl_give isl_basic_set *isl_basic_set_remove_divs( |
| __isl_take isl_basic_set *bset); |
| __isl_give isl_set *isl_set_remove_divs( |
| __isl_take isl_set *set); |
| |
| #include <isl/map.h> |
| __isl_give isl_basic_map *isl_basic_map_remove_divs( |
| __isl_take isl_basic_map *bmap); |
| __isl_give isl_map *isl_map_remove_divs( |
| __isl_take isl_map *map); |
| |
| #include <isl/union_set.h> |
| __isl_give isl_union_set *isl_union_set_remove_divs( |
| __isl_take isl_union_set *bset); |
| |
| #include <isl/union_map.h> |
| __isl_give isl_union_map *isl_union_map_remove_divs( |
| __isl_take isl_union_map *bmap); |
| |
| 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_basic_map * |
| isl_basic_map_remove_divs_involving_dims( |
| __isl_take isl_basic_map *bmap, |
| 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_basic_set * |
| isl_basic_set_remove_unknown_divs( |
| __isl_take isl_basic_set *bset); |
| __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 |
| |
| #include <isl/union_set.h> |
| isl_stat isl_union_set_foreach_set( |
| __isl_keep isl_union_set *uset, |
| isl_stat (*fn)(__isl_take isl_set *set, void *user), |
| void *user); |
| |
| #include <isl/union_map.h> |
| isl_stat isl_union_map_foreach_map( |
| __isl_keep isl_union_map *umap, |
| isl_stat (*fn)(__isl_take isl_map *map, void *user), |
| void *user); |
| isl_bool isl_union_map_every_map( |
| __isl_keep isl_union_map *umap, |
| isl_bool (*test)(__isl_keep isl_map *map, |
| void *user), |
| void *user); |
| |
| These functions call the callback function once for each |
| (pair of) space(s) for which there are elements in the input. |
| The argument to the callback contains all elements in the input |
| with that (pair of) space(s). |
| The C<isl_union_map_every_map> variant check whether each |
| call to the callback returns true and stops checking as soon as one |
| of these calls returns false. |
| |
| The number of sets or maps in a union set or map can be obtained |
| from |
| |
| int isl_union_set_n_set(__isl_keep isl_union_set *uset); |
| int isl_union_map_n_map(__isl_keep isl_union_map *umap); |
| |
| To extract the set or map in a given space from a union, use |
| |
| __isl_give isl_set *isl_union_set_extract_set( |
| __isl_keep isl_union_set *uset, |
| __isl_take isl_space *space); |
| __isl_give isl_map *isl_union_map_extract_map( |
| __isl_keep isl_union_map *umap, |
| __isl_take isl_space *space); |
| |
| To iterate over all the basic sets or maps in a set or map, use |
| |
| isl_stat isl_set_foreach_basic_set(__isl_keep isl_set *set, |
| isl_stat (*fn)(__isl_take isl_basic_set *bset, |
| void *user), |
| void *user); |
| isl_stat isl_map_foreach_basic_map(__isl_keep isl_map *map, |
| isl_stat (*fn)(__isl_take isl_basic_map *bmap, |
| void *user), |
| void *user); |
| |
| The callback function C<fn> should return C<isl_stat_ok> if successful and |
| C<isl_stat_error> if an error occurs. In the latter case, or if any other error |
| occurs, the above functions will return C<isl_stat_error>. |
| |
| It should be noted that C<isl> does not guarantee that |
| the basic sets or maps passed to C<fn> are disjoint. |
| If this is required, then the user should call one of |
| the following functions first. |
| |
| __isl_give isl_set *isl_set_make_disjoint( |
| __isl_take isl_set *set); |
| __isl_give isl_map *isl_map_make_disjoint( |
| __isl_take isl_map *map); |
| |
| The number of basic sets in a set can be obtained |
| or the number of basic maps in a map can be obtained |
| from |
| |
| #include <isl/set.h> |
| int isl_set_n_basic_set(__isl_keep isl_set *set); |
| |
| #include <isl/map.h> |
| int isl_map_n_basic_map(__isl_keep isl_map *map); |
| |
| It is also possible to obtain a list of (basic) sets from a set |
| or union set, a list of basic maps from a map and a list of maps from a union |
| map. |
| |
| #include <isl/set.h> |
| __isl_give isl_basic_set_list *isl_set_get_basic_set_list( |
| __isl_keep isl_set *set); |
| |
| #include <isl/union_set.h> |
| __isl_give isl_basic_set_list * |
| isl_union_set_get_basic_set_list( |
| __isl_keep isl_union_set *uset); |
| __isl_give isl_set_list *isl_union_set_get_set_list( |
| __isl_keep isl_union_set *uset); |
| |
| #include <isl/map.h> |
| __isl_give isl_basic_map_list *isl_map_get_basic_map_list( |
| __isl_keep isl_map *map); |
| |
| #include <isl/union_map.h> |
| __isl_give isl_map_list *isl_union_map_get_map_list( |
| __isl_keep isl_union_map *umap); |
| |
| The returned list can be manipulated using the functions in L<"Lists">. |
| |
| To iterate over the constraints of a basic set or map, use |
| |
| #include <isl/constraint.h> |
| |
| int isl_basic_set_n_constraint( |
| __isl_keep isl_basic_set *bset); |
| isl_stat isl_basic_set_foreach_constraint( |
| __isl_keep isl_basic_set *bset, |
| isl_stat (*fn)(__isl_take isl_constraint *c, |
| void *user), |
| void *user); |
| int isl_basic_map_n_constraint( |
| __isl_keep isl_basic_map *bmap); |
| isl_stat isl_basic_map_foreach_constraint( |
| __isl_keep isl_basic_map *bmap, |
| isl_stat (*fn)(__isl_take isl_constraint *c, |
| void *user), |
| void *user); |
| __isl_null isl_constraint *isl_constraint_free( |
| __isl_take isl_constraint *c); |
| |
| Again, the callback function C<fn> should return C<isl_stat_ok> |
| if successful and |
| C<isl_stat_error> if an error occurs. In the latter case, or if any other error |
| occurs, the above functions will return C<isl_stat_error>. |
| The constraint C<c> represents either an equality or an inequality. |
| Use the following function to find out whether a constraint |
| represents an equality. If not, it represents an inequality. |
| |
| isl_bool isl_constraint_is_equality( |
| __isl_keep isl_constraint *constraint); |
| |
| It is also possible to obtain a list of constraints from a basic |
| map or set |
| |
| #include <isl/constraint.h> |
| __isl_give isl_constraint_list * |
| isl_basic_map_get_constraint_list( |
| __isl_keep isl_basic_map *bmap); |
| __isl_give isl_constraint_list * |
| isl_basic_set_get_constraint_list( |
| __isl_keep isl_basic_set *bset); |
| |
| These functions require that all existentially quantified variables |
| have an explicit representation. |
| The returned list can be manipulated using the functions in L<"Lists">. |
| |
| The coefficients of the constraints can be inspected using |
| the following functions. |
| |
| isl_bool isl_constraint_is_lower_bound( |
| __isl_keep isl_constraint *constraint, |
| enum isl_dim_type type, unsigned pos); |
| isl_bool isl_constraint_is_upper_bound( |
| __isl_keep isl_constraint *constraint, |
| enum isl_dim_type type, unsigned pos); |
| __isl_give isl_val *isl_constraint_get_constant_val( |
| __isl_keep isl_constraint *constraint); |
| __isl_give isl_val *isl_constraint_get_coefficient_val( |
| __isl_keep isl_constraint *constraint, |
| enum isl_dim_type type, int pos); |
| |
| The explicit representations of the existentially quantified |
| variables can be inspected using the following function. |
| Note that the user is only allowed to use this function |
| if the inspected set or map is the result of a call |
| to C<isl_set_compute_divs> or C<isl_map_compute_divs>. |
| The existentially quantified variable is equal to the floor |
| of the returned affine expression. The affine expression |
| itself can be inspected using the functions in |
| L</"Functions">. |
| |
| __isl_give isl_aff *isl_constraint_get_div( |
| __isl_keep isl_constraint *constraint, int pos); |
| |
| To obtain the constraints of a basic set or map in matrix |
| form, use the following functions. |
| |
| __isl_give isl_mat *isl_basic_set_equalities_matrix( |
| __isl_keep isl_basic_set *bset, |
| enum isl_dim_type c1, enum isl_dim_type c2, |
| enum isl_dim_type c3, enum isl_dim_type c4); |
| __isl_give isl_mat *isl_basic_set_inequalities_matrix( |
| __isl_keep isl_basic_set *bset, |
| enum isl_dim_type c1, enum isl_dim_type c2, |
| enum isl_dim_type c3, enum isl_dim_type c4); |
| __isl_give isl_mat *isl_basic_map_equalities_matrix( |
| __isl_keep isl_basic_map *bmap, |
| enum isl_dim_type c1, |
| enum isl_dim_type c2, enum isl_dim_type c3, |
| enum isl_dim_type c4, enum isl_dim_type c5); |
| __isl_give isl_mat *isl_basic_map_inequalities_matrix( |
| __isl_keep isl_basic_map *bmap, |
| enum isl_dim_type c1, |
| enum isl_dim_type c2, enum isl_dim_type c3, |
| enum isl_dim_type c4, enum isl_dim_type c5); |
| |
| The C<isl_dim_type> arguments dictate the order in which |
| different kinds of variables appear in the resulting matrix. |
| For set inputs, they should be a permutation of |
| C<isl_dim_cst>, C<isl_dim_param>, C<isl_dim_set> and C<isl_dim_div>. |
| For map inputs, they should be a permutation of |
| C<isl_dim_cst>, C<isl_dim_param>, |
| C<isl_dim_in>, C<isl_dim_out> and C<isl_dim_div>. |
| |
| =head2 Points |
| |
| Points are elements of a set. They can be used to construct |
| simple sets (boxes) or they can be used to represent the |
| individual elements of a set. |
| The zero point (the origin) can be created using |
| |
| __isl_give isl_point *isl_point_zero(__isl_take isl_space *space); |
| |
| The coordinates of a point can be inspected, set and changed |
| using |
| |
| __isl_give isl_val *isl_point_get_coordinate_val( |
| __isl_keep isl_point *pnt, |
| enum isl_dim_type type, int pos); |
| __isl_give isl_point *isl_point_set_coordinate_val( |
| __isl_take isl_point *pnt, |
| enum isl_dim_type type, int pos, |
| __isl_take isl_val *v); |
| |
| __isl_give isl_point *isl_point_add_ui( |
| __isl_take isl_point *pnt, |
| enum isl_dim_type type, int pos, unsigned val); |
| __isl_give isl_point *isl_point_sub_ui( |
| __isl_take isl_point *pnt, |
| enum isl_dim_type type, int pos, unsigned val); |
| |
| Points can be copied or freed using |
| |
| __isl_give isl_point *isl_point_copy( |
| __isl_keep isl_point *pnt); |
| __isl_null isl_point *isl_point_free( |
| __isl_take isl_point *pnt); |
| |
| A singleton set can be created from a point using |
| |
| __isl_give isl_basic_set *isl_basic_set_from_point( |
| __isl_take isl_point *pnt); |
| __isl_give isl_set *isl_set_from_point( |
| __isl_take isl_point *pnt); |
| __isl_give isl_union_set *isl_union_set_from_point( |
| __isl_take isl_point *pnt); |
| |
| and a box can be created from two opposite extremal points using |
| |
| __isl_give isl_basic_set *isl_basic_set_box_from_points( |
| __isl_take isl_point *pnt1, |
| __isl_take isl_point *pnt2); |
| __isl_give isl_set *isl_set_box_from_points( |
| __isl_take isl_point *pnt1, |
| __isl_take isl_point *pnt2); |
| |
| All elements of a B<bounded> (union) set can be enumerated using |
| the following functions. |
| |
| isl_stat isl_set_foreach_point(__isl_keep isl_set *set, |
| isl_stat (*fn)(__isl_take isl_point *pnt, |
| void *user), |
| void *user); |
| isl_stat isl_union_set_foreach_point( |
| __isl_keep isl_union_set *uset, |
| isl_stat (*fn)(__isl_take isl_point *pnt, |
| void *user), |
| void *user); |
| |
| The function C<fn> is called for each integer point in |
| C<set> with as second argument the last argument of |
| the C<isl_set_foreach_point> call. The function C<fn> |
| should return C<isl_stat_ok> on success and C<isl_stat_error> on failure. |
| In the latter case, C<isl_set_foreach_point> will stop |
| enumerating and return C<isl_stat_error> as well. |
| If the enumeration is performed successfully and to completion, |
| then C<isl_set_foreach_point> returns C<isl_stat_ok>. |
| |
| To obtain a single point of a (basic or union) set, use |
| |
| __isl_give isl_point *isl_basic_set_sample_point( |
| __isl_take isl_basic_set *bset); |
| __isl_give isl_point *isl_set_sample_point( |
| __isl_take isl_set *set); |
| __isl_give isl_point *isl_union_set_sample_point( |
| __isl_take isl_union_set *uset); |
| |
| If C<set> does not contain any (integer) points, then the |
| resulting point will be ``void'', a property that can be |
| tested using |
| |
| isl_bool isl_point_is_void(__isl_keep isl_point *pnt); |
| |
| =head2 Functions |
| |
| Besides sets and relation, C<isl> also supports various types of functions. |
| Each of these types is derived from the value type (see L</"Values">) |
| or from one of two primitive function types |
| through the application of zero or more type constructors. |
| We first describe the primitive type and then we describe |
| the types derived from these primitive types. |
| |
| =head3 Primitive Functions |
| |
| C<isl> support two primitive function types, quasi-affine |
| expressions and quasipolynomials. |
| A quasi-affine expression is defined either over a parameter |
| space or over a set and is composed of integer constants, |
| parameters and set variables, addition, subtraction and |
| integer division by an integer constant. |
| For example, the quasi-affine expression |
| |
| [n] -> { [x] -> [2*floor((4 n + x)/9)] } |
| |
| maps C<x> to C<2*floor((4 n + x)/9>. |
| A quasipolynomial is a polynomial expression in quasi-affine |
| expression. That is, it additionally allows for multiplication. |
| Note, though, that it is not allowed to construct an integer |
| division of an expression involving multiplications. |
| Here is an example of a quasipolynomial that is not |
| quasi-affine expression |
| |
| [n] -> { [x] -> (n*floor((4 n + x)/9)) } |
| |
| Note that the external representations of quasi-affine expressions |
| and quasipolynomials are different. Quasi-affine expressions |
| use a notation with square brackets just like binary relations, |
| while quasipolynomials do not. This might change at some point. |
| |
| If a primitive function is defined over a parameter space, |
| then the space of the function itself is that of a set. |
| If it is defined over a set, then the space of the function |
| is that of a relation. In both cases, the set space (or |
| the output space) is single-dimensional, anonymous and unstructured. |
| To create functions with multiple dimensions or with other kinds |
| of set or output spaces, use multiple expressions |
| (see L</"Multiple Expressions">). |
| |
| =over |
| |
| =item * Quasi-affine Expressions |
| |
| Besides the expressions described above, a quasi-affine |
| expression can also be set to NaN. Such expressions |
| typically represent a failure to represent a result |
| as a quasi-affine expression. |
| |
| The zero quasi affine expression or the quasi affine expression |
| that is equal to a given value, parameter or |
| a specified dimension on a given domain can be created using |
| |
| #include <isl/aff.h> |
| __isl_give isl_aff *isl_aff_zero_on_domain( |
| __isl_take isl_local_space *ls); |
| __isl_give isl_aff *isl_aff_val_on_domain( |
| __isl_take isl_local_space *ls, |
| __isl_take isl_val *val); |
| __isl_give isl_aff *isl_aff_param_on_domain_space_id( |
| __isl_take isl_space *space, |
| __isl_take isl_id *id); |
| __isl_give isl_aff *isl_aff_var_on_domain( |
| __isl_take isl_local_space *ls, |
| enum isl_dim_type type, unsigned pos); |
| __isl_give isl_aff *isl_aff_nan_on_domain( |
| __isl_take isl_local_space *ls); |
| |
| The space passed to C<isl_aff_param_on_domain_space_id> |
| is required to have a parameter with the given identifier. |
| |
| Quasi affine expressions can be copied and freed using |
| |
| #include <isl/aff.h> |
| __isl_give isl_aff *isl_aff_copy( |
| __isl_keep isl_aff *aff); |
| __isl_null isl_aff *isl_aff_free( |
| __isl_take isl_aff *aff); |
| |
| A (rational) bound on a dimension can be extracted from an C<isl_constraint> |
| using the following function. The constraint is required to have |
| a non-zero coefficient for the specified dimension. |
| |
| #include <isl/constraint.h> |
| __isl_give isl_aff *isl_constraint_get_bound( |
| __isl_keep isl_constraint *constraint, |
| enum isl_dim_type type, int pos); |
| |
| The entire affine expression of the constraint can also be extracted |
| using the following function. |
| |
| #include <isl/constraint.h> |
| __isl_give isl_aff *isl_constraint_get_aff( |
| __isl_keep isl_constraint *constraint); |
| |
| Conversely, an equality constraint equating |
| the affine expression to zero or an inequality constraint enforcing |
| the affine expression to be non-negative, can be constructed using |
| |
| __isl_give isl_constraint *isl_equality_from_aff( |
| __isl_take isl_aff *aff); |
| __isl_give isl_constraint *isl_inequality_from_aff( |
| __isl_take isl_aff *aff); |
| |
| The coefficients and the integer divisions of an affine expression |
| can be inspected using the following functions. |
| |
| #include <isl/aff.h> |
| __isl_give isl_val *isl_aff_get_constant_val( |
| __isl_keep isl_aff *aff); |
| __isl_give isl_val *isl_aff_get_coefficient_val( |
| __isl_keep isl_aff *aff, |
| enum isl_dim_type type, int pos); |
| int isl_aff_coefficient_sgn(__isl_keep isl_aff *aff, |
| enum isl_dim_type type, int pos); |
| __isl_give isl_val *isl_aff_get_denominator_val( |
| __isl_keep isl_aff *aff); |
| __isl_give isl_aff *isl_aff_get_div( |
| __isl_keep isl_aff *aff, int pos); |
| |
| They can be modified using the following functions. |
| |
| #include <isl/aff.h> |
| __isl_give isl_aff *isl_aff_set_constant_si( |
| __isl_take isl_aff *aff, int v); |
| __isl_give isl_aff *isl_aff_set_constant_val( |
| __isl_take isl_aff *aff, __isl_take isl_val *v); |
| __isl_give isl_aff *isl_aff_set_coefficient_si( |
| __isl_take isl_aff *aff, |
| enum isl_dim_type type, int pos, int v); |
| __isl_give isl_aff *isl_aff_set_coefficient_val( |
| __isl_take isl_aff *aff, |
| enum isl_dim_type type, int pos, |
| __isl_take isl_val *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_val( |
| __isl_take isl_aff *aff, __isl_take isl_val *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_si( |
| __isl_take isl_aff *aff, |
| enum isl_dim_type type, int pos, int v); |
| __isl_give isl_aff *isl_aff_add_coefficient_val( |
| __isl_take isl_aff *aff, |
| enum isl_dim_type type, int pos, |
| __isl_take isl_val *v); |
| |
| Note that C<isl_aff_set_constant_si> and C<isl_aff_set_coefficient_si> |
| set the I<numerator> of the constant or coefficient, while |
| C<isl_aff_set_constant_val> and C<isl_aff_set_coefficient_val> set |
| the constant or coefficient as a whole. |
| The C<add_constant> and C<add_coefficient> functions add an integer |
| or rational value to |
| the possibly rational constant or coefficient. |
| The C<add_constant_num> functions add an integer value to |
| the numerator. |
| |
| =item * Quasipolynomials |
| |
| Some simple quasipolynomials can be created using the following functions. |
| |
| #include <isl/polynomial.h> |
| __isl_give isl_qpolynomial *isl_qpolynomial_zero_on_domain( |
| __isl_take isl_space *domain); |
| __isl_give isl_qpolynomial *isl_qpolynomial_one_on_domain( |
| __isl_take isl_space *domain); |
| __isl_give isl_qpolynomial *isl_qpolynomial_infty_on_domain( |
| __isl_take isl_space *domain); |
| __isl_give isl_qpolynomial *isl_qpolynomial_neginfty_on_domain( |
| __isl_take isl_space *domain); |
| __isl_give isl_qpolynomial *isl_qpolynomial_nan_on_domain( |
| __isl_take isl_space *domain); |
| __isl_give isl_qpolynomial *isl_qpolynomial_val_on_domain( |
| __isl_take isl_space *domain, |
| __isl_take isl_val *val); |
| __isl_give isl_qpolynomial *isl_qpolynomial_var_on_domain( |
| __isl_take isl_space *domain, |
| enum isl_dim_type type, unsigned pos); |
| __isl_give isl_qpolynomial *isl_qpolynomial_from_aff( |
| __isl_take isl_aff *aff); |
| |
| Recall that the space in which a quasipolynomial lives is a map space |
| with a one-dimensional range. The C<domain> argument in some of |
| the functions above corresponds to the domain of this map space. |
| |
| Quasipolynomials can be copied and freed again using the following |
| functions. |
| |
| #include <isl/polynomial.h> |
| __isl_give isl_qpolynomial *isl_qpolynomial_copy( |
| __isl_keep isl_qpolynomial *qp); |
| __isl_null isl_qpolynomial *isl_qpolynomial_free( |
| __isl_take isl_qpolynomial *qp); |
| |
| The constant term of a quasipolynomial can be extracted using |
| |
| __isl_give isl_val *isl_qpolynomial_get_constant_val( |
| __isl_keep isl_qpolynomial *qp); |
| |
| To iterate over all terms in a quasipolynomial, |
| use |
| |
| isl_stat isl_qpolynomial_foreach_term( |
| __isl_keep isl_qpolynomial *qp, |
| isl_stat (*fn)(__isl_take isl_term *term, |
| void *user), void *user); |
| |
| The terms themselves can be inspected and freed using |
| these functions |
| |
| unsigned isl_term_dim(__isl_keep isl_term *term, |
| enum isl_dim_type type); |
| __isl_give isl_val *isl_term_get_coefficient_val( |
| __isl_keep isl_term *term); |
| int isl_term_get_exp(__isl_keep isl_term *term, |
| enum isl_dim_type type, unsigned pos); |
| __isl_give isl_aff *isl_term_get_div( |
| __isl_keep isl_term *term, unsigned pos); |
| void isl_term_free(__isl_take isl_term *term); |
| |
| Each term is a product of parameters, set variables and |
| integer divisions. The function C<isl_term_get_exp> |
| returns the exponent of a given dimensions in the given term. |
| |
| =back |
| |
| =head3 Reductions |
| |
| A reduction represents a maximum or a minimum of its |
| base expressions. |
| The only reduction type defined by C<isl> is |
| C<isl_qpolynomial_fold>. |
| |
| There are currently no functions to directly create such |
| objects, but they do appear in the piecewise quasipolynomial |
| reductions returned by the C<isl_pw_qpolynomial_bound> function. |
| See |
| L</"Bounds on Piecewise Quasipolynomials and Piecewise Quasipolynomial Reductions">. |
| |
| Reductions can be copied and freed using |
| the following functions. |
| |
| #include <isl/polynomial.h> |
| __isl_give isl_qpolynomial_fold * |
| isl_qpolynomial_fold_copy( |
| __isl_keep isl_qpolynomial_fold *fold); |
| void isl_qpolynomial_fold_free( |
| __isl_take isl_qpolynomial_fold *fold); |
| |
| To iterate over all quasipolynomials in a reduction, use |
| |
| isl_stat isl_qpolynomial_fold_foreach_qpolynomial( |
| __isl_keep isl_qpolynomial_fold *fold, |
| isl_stat (*fn)(__isl_take isl_qpolynomial *qp, |
| void *user), void *user); |
| |
| =head3 Multiple Expressions |
| |
| A multiple expression represents a sequence of zero or |
| more base expressions, all defined on the same domain space. |
| The domain space of the multiple expression is the same |
| as that of the base expressions, but the range space |
| can be any space. In case the base expressions have |
| a set space, the corresponding multiple expression |
| also has a set space. |
| Objects of the value type do not have an associated space. |
| The space of a multiple value is therefore always a set space. |
| Similarly, the space of a multiple union piecewise |
| affine expression is always a set space. |
| If the base expressions are not total, then |
| a corresponding zero-dimensional multiple expression may |
| have an explicit domain that keeps track of the domain |
| outside of any base expressions. |
| |
| The multiple expression types defined by C<isl> |
| are C<isl_multi_val>, C<isl_multi_aff>, C<isl_multi_pw_aff>, |
| C<isl_multi_union_pw_aff>. |
| |
| A multiple expression with the value zero for |
| each output (or set) dimension can be created |
| using the following functions. |
| |
| #include <isl/val.h> |
| __isl_give isl_multi_val *isl_multi_val_zero( |
| __isl_take isl_space *space); |
| |
| #include <isl/aff.h> |
| __isl_give isl_multi_aff *isl_multi_aff_zero( |
| __isl_take isl_space *space); |
| __isl_give isl_multi_pw_aff *isl_multi_pw_aff_zero( |
| __isl_take isl_space *space); |
| __isl_give isl_multi_union_pw_aff * |
| isl_multi_union_pw_aff_zero( |
| __isl_take isl_space *space); |
| |
| Since there is no canonical way of representing a zero |
| value of type C<isl_union_pw_aff>, the space passed |
| to C<isl_multi_union_pw_aff_zero> needs to be zero-dimensional. |
| |
| An identity function can be created using the following |
| functions. The space needs to be that of a relation |
| with the same number of input and output dimensions. |
| |
| #include <isl/aff.h> |
| __isl_give isl_multi_aff *isl_multi_aff_identity( |
| __isl_take isl_space *space); |
| __isl_give isl_multi_pw_aff *isl_multi_pw_aff_identity( |
| __isl_take isl_space *space); |
| |
| A function that performs a projection on a universe |
| relation or set can be created using the following functions. |
| See also the corresponding |
| projection operations in L</"Unary Operations">. |
| |
| #include <isl/aff.h> |
| __isl_give isl_multi_aff *isl_multi_aff_domain_map( |
| __isl_take isl_space *space); |
| __isl_give isl_multi_aff *isl_multi_aff_range_map( |
| __isl_take isl_space *space); |
| __isl_give isl_multi_aff *isl_multi_aff_project_out_map( |
| __isl_take isl_space *space, |
| enum isl_dim_type type, |
| unsigned first, unsigned n); |
| |
| A multiple expression can be created from a single |
| base expression using the following functions. |
| The space of the created multiple expression is the same |
| as that of the base expression, except for |
| C<isl_multi_union_pw_aff_from_union_pw_aff> where the input |
| lives in a parameter space and the output lives |
| in a single-dimensional set space. |
| |
| #include <isl/aff.h> |
| __isl_give isl_multi_aff *isl_multi_aff_from_aff( |
| __isl_take isl_aff *aff); |
| __isl_give isl_multi_pw_aff *isl_multi_pw_aff_from_pw_aff( |
| __isl_take isl_pw_aff *pa); |
| __isl_give isl_multi_union_pw_aff * |
| isl_multi_union_pw_aff_from_union_pw_aff( |
| __isl_take isl_union_pw_aff *upa); |
| |
| A multiple expression can be created from a list |
| of base expression in a specified space. |
| The domain of this space needs to be the same |
| as the domains of the base expressions in the list. |
| If the base expressions have a set space (or no associated space), |
| then this space also needs to be a set space. |
| |
| #include <isl/val.h> |
| __isl_give isl_multi_val *isl_multi_val_from_val_list( |
| __isl_take isl_space *space, |
| __isl_take isl_val_list *list); |
| |
| #include <isl/aff.h> |
| __isl_give isl_multi_aff *isl_multi_aff_from_aff_list( |
| __isl_take isl_space *space, |
| __isl_take isl_aff_list *list); |
| __isl_give isl_multi_pw_aff * |
| isl_multi_pw_aff_from_pw_aff_list( |
| __isl_take isl_space *space, |
| __isl_take isl_pw_aff_list *list); |
| __isl_give isl_multi_union_pw_aff * |
| isl_multi_union_pw_aff_from_union_pw_aff_list( |
| __isl_take isl_space *space, |
| __isl_take isl_union_pw_aff_list *list); |
| |
| As a convenience, a multiple piecewise expression can |
| also be created from a multiple expression. |
| Each piecewise expression in the result has a single |
| universe cell. |
| |
| #include <isl/aff.h> |
| __isl_give isl_multi_pw_aff * |
| isl_multi_pw_aff_from_multi_aff( |
| __isl_take isl_multi_aff *ma); |
| |
| Similarly, a multiple union expression can be |
| created from a multiple expression. |
| |
| #include <isl/aff.h> |
| __isl_give isl_multi_union_pw_aff * |
| isl_multi_union_pw_aff_from_multi_aff( |
| __isl_take isl_multi_aff *ma); |
| __isl_give isl_multi_union_pw_aff * |
| isl_multi_union_pw_aff_from_multi_pw_aff( |
| __isl_take isl_multi_pw_aff *mpa); |
| |
| A multiple quasi-affine expression can be created from |
| a multiple value with a given domain space using the following |
| function. |
| |
| #include <isl/aff.h> |
| __isl_give isl_multi_aff * |
| isl_multi_aff_multi_val_on_space( |
| __isl_take isl_space *space, |
| __isl_take isl_multi_val *mv); |
| |
| Similarly, |
| a multiple union piecewise affine expression can be created from |
| a multiple value with a given domain or |
| a (piecewise) multiple affine expression with a given domain |
| using the following functions. |
| |
| #include <isl/aff.h> |
| __isl_give isl_multi_union_pw_aff * |
| isl_multi_union_pw_aff_multi_val_on_domain( |
| __isl_take isl_union_set *domain, |
| __isl_take isl_multi_val *mv); |
| __isl_give isl_multi_union_pw_aff * |
| isl_multi_union_pw_aff_multi_aff_on_domain( |
| __isl_take isl_union_set *domain, |
| __isl_take isl_multi_aff *ma); |
| __isl_give isl_multi_union_pw_aff * |
| isl_multi_union_pw_aff_pw_multi_aff_on_domain( |
| __isl_take isl_union_set *domain, |
| __isl_take isl_pw_multi_aff *pma); |
| |
| Multiple expressions can be copied and freed using |
| the following functions. |
| |
| #include <isl/val.h> |
| __isl_give isl_multi_val *isl_multi_val_copy( |
| __isl_keep isl_multi_val *mv); |
| __isl_null isl_multi_val *isl_multi_val_free( |
| __isl_take isl_multi_val *mv); |
| |
| #include <isl/aff.h> |
| __isl_give isl_multi_aff *isl_multi_aff_copy( |
| __isl_keep isl_multi_aff *maff); |
| __isl_null isl_multi_aff *isl_multi_aff_free( |
| __isl_take isl_multi_aff *maff); |
| __isl_give isl_multi_pw_aff *isl_multi_pw_aff_copy( |
| __isl_keep isl_multi_pw_aff *mpa); |
| __isl_null isl_multi_pw_aff *isl_multi_pw_aff_free( |
| __isl_take isl_multi_pw_aff *mpa); |
| __isl_give isl_multi_union_pw_aff * |
| isl_multi_union_pw_aff_copy( |
| __isl_keep isl_multi_union_pw_aff *mupa); |
| __isl_null isl_multi_union_pw_aff * |
| isl_multi_union_pw_aff_free( |
| __isl_take isl_multi_union_pw_aff *mupa); |
| |
| The base expression at a given position of a multiple |
| expression can be extracted using the following functions. |
| |
| #include <isl/val.h> |
| __isl_give isl_val *isl_multi_val_get_val( |
| __isl_keep isl_multi_val *mv, int pos); |
| |
| #include <isl/aff.h> |
| __isl_give isl_aff *isl_multi_aff_get_aff( |
| __isl_keep isl_multi_aff *multi, int pos); |
| __isl_give isl_pw_aff *isl_multi_pw_aff_get_pw_aff( |
| __isl_keep isl_multi_pw_aff *mpa, int pos); |
| __isl_give isl_union_pw_aff * |
| isl_multi_union_pw_aff_get_union_pw_aff( |
| __isl_keep isl_multi_union_pw_aff *mupa, int pos); |
| |
| It can be replaced using the following functions. |
| |
| #include <isl/val.h> |
| __isl_give isl_multi_val *isl_multi_val_set_val( |
| __isl_take isl_multi_val *mv, int pos, |
| __isl_take isl_val *val); |
| |
| #include <isl/aff.h> |
| __isl_give isl_multi_aff *isl_multi_aff_set_aff( |
| __isl_take isl_multi_aff *multi, int pos, |
| __isl_take isl_aff *aff); |
| __isl_give isl_multi_union_pw_aff * |
| isl_multi_union_pw_aff_set_union_pw_aff( |
| __isl_take isl_multi_union_pw_aff *mupa, int pos, |
| __isl_take isl_union_pw_aff *upa); |
| |
| As a convenience, a sequence of base expressions that have |
| their domains in a given space can be extracted from a sequence |
| of union expressions using the following function. |
| |
| #include <isl/aff.h> |
| __isl_give isl_multi_pw_aff * |
| isl_multi_union_pw_aff_extract_multi_pw_aff( |
| __isl_keep isl_multi_union_pw_aff *mupa, |
| __isl_take isl_space *space); |
| |
| Note that there is a difference between C<isl_multi_union_pw_aff> |
| and C<isl_union_pw_multi_aff> objects. The first is a sequence |
| of unions of piecewise expressions, while the second is a union |
| of piecewise sequences. In particular, multiple affine expressions |
| in an C<isl_union_pw_multi_aff> may live in different spaces, |
| while there is only a single multiple expression in |
| an C<isl_multi_union_pw_aff>, which can therefore only live |
| in a single space. This means that not every |
| C<isl_union_pw_multi_aff> can be converted to |
| an C<isl_multi_union_pw_aff>. Conversely, the elements |
| of an C<isl_multi_union_pw_aff> may be defined over different domains, |
| while each multiple expression inside an C<isl_union_pw_multi_aff> |
| has a single domain. The conversion of an C<isl_union_pw_multi_aff> |
| of dimension greater than one may therefore not be exact. |
| The following functions can |
| be used to perform these conversions when they are possible. |
| |
| #include <isl/aff.h> |
| __isl_give isl_multi_union_pw_aff * |
| isl_multi_union_pw_aff_from_union_pw_multi_aff( |
| __isl_take isl_union_pw_multi_aff *upma); |
| __isl_give isl_union_pw_multi_aff * |
| isl_union_pw_multi_aff_from_multi_union_pw_aff( |
| __isl_take isl_multi_union_pw_aff *mupa); |
| |
| =head3 Piecewise Expressions |
| |
| A piecewise expression is an expression that is described |
| using zero or more base expression defined over the same |
| number of cells in the domain space of the base expressions. |
| All base expressions are defined over the same |
| domain space and the cells are disjoint. |
| The space of a piecewise expression is the same as |
| that of the base expressions. |
| If the union of the cells is a strict subset of the domain |
| space, then the value of the piecewise expression outside |
| this union is different for types derived from quasi-affine |
| expressions and those derived from quasipolynomials. |
| Piecewise expressions derived from quasi-affine expressions |
| are considered to be undefined outside the union of their cells. |
| Piecewise expressions derived from quasipolynomials |
| are considered to be zero outside the union of their cells. |
| |
| Piecewise quasipolynomials are mainly used by the C<barvinok> |
| library for representing the number of elements in a parametric set or map. |
| For example, the piecewise quasipolynomial |
| |
| [n] -> { [x] -> ((1 + n) - x) : x <= n and x >= 0 } |
| |
| represents the number of points in the map |
| |
| [n] -> { [x] -> [y] : x,y >= 0 and 0 <= x + y <= n } |
| |
| The piecewise expression types defined by C<isl> |
| are C<isl_pw_aff>, C<isl_pw_multi_aff>, |
| C<isl_pw_qpolynomial> and C<isl_pw_qpolynomial_fold>. |
| |
| A piecewise expression with no cells can be created using |
| the following functions. |
| |
| #include <isl/aff.h> |
| __isl_give isl_pw_aff *isl_pw_aff_empty( |
| __isl_take isl_space *space); |
| __isl_give isl_pw_multi_aff *isl_pw_multi_aff_empty( |
| __isl_take isl_space *space); |
| |
| A piecewise expression with a single universe cell can be |
| created using the following functions. |
| |
| #include <isl/aff.h> |
| __isl_give isl_pw_aff *isl_pw_aff_from_aff( |
| __isl_take isl_aff *aff); |
| __isl_give isl_pw_multi_aff * |
| isl_pw_multi_aff_from_multi_aff( |
| __isl_take isl_multi_aff *ma); |
| |
| #include <isl/polynomial.h> |
| __isl_give isl_pw_qpolynomial * |
| isl_pw_qpolynomial_from_qpolynomial( |
| __isl_take isl_qpolynomial *qp); |
| |
| A piecewise expression with a single specified cell can be |
| created using the following functions. |
| |
| #include <isl/aff.h> |
| __isl_give isl_pw_aff *isl_pw_aff_alloc( |
| __isl_take isl_set *set, __isl_take isl_aff *aff); |
| __isl_give isl_pw_multi_aff *isl_pw_multi_aff_alloc( |
| __isl_take isl_set *set, |
| __isl_take isl_multi_aff *maff); |
| |
| #include <isl/polynomial.h> |
| __isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_alloc( |
| __isl_take isl_set *set, |
| __isl_take isl_qpolynomial *qp); |
| |
| The following convenience functions first create a base expression and |
| then create a piecewise expression over a universe domain. |
| |
| #include <isl/aff.h> |
| __isl_give isl_pw_aff *isl_pw_aff_zero_on_domain( |
| __isl_take isl_local_space *ls); |
| __isl_give isl_pw_aff *isl_pw_aff_var_on_domain( |
| __isl_take isl_local_space *ls, |
| enum isl_dim_type type, unsigned pos); |
| __isl_give isl_pw_aff *isl_pw_aff_nan_on_domain( |
| __isl_take isl_local_space *ls); |
| __isl_give isl_pw_multi_aff *isl_pw_multi_aff_zero( |
| __isl_take isl_space *space); |
| __isl_give isl_pw_multi_aff *isl_pw_multi_aff_identity( |
| __isl_take isl_space *space); |
| __isl_give isl_pw_multi_aff *isl_pw_multi_aff_range_map( |
| __isl_take isl_space *space); |
| __isl_give isl_pw_multi_aff * |
| isl_pw_multi_aff_project_out_map( |
| __isl_take isl_space *space, |
| enum isl_dim_type type, |
| unsigned first, unsigned n); |
| |
| #include <isl/polynomial.h> |
| __isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_zero( |
| __isl_take isl_space *space); |
| |
| The following convenience functions first create a base expression and |
| then create a piecewise expression over a given domain. |
| |
| #include <isl/aff.h> |
| __isl_give isl_pw_aff *isl_pw_aff_val_on_domain( |
| __isl_take isl_set *domain, |
| __isl_take isl_val *v); |
| __isl_give isl_pw_multi_aff * |
| isl_pw_multi_aff_multi_val_on_domain( |
| __isl_take isl_set *domain, |
| __isl_take isl_multi_val *mv); |
| |
| As a convenience, a piecewise multiple expression can |
| also be created from a piecewise expression. |
| Each multiple expression in the result is derived |
| from the corresponding base expression. |
| |
| #include <isl/aff.h> |
| __isl_give isl_pw_multi_aff *isl_pw_multi_aff_from_pw_aff( |
| __isl_take isl_pw_aff *pa); |
| |
| Similarly, a piecewise quasipolynomial can be |
| created from a piecewise quasi-affine expression using |
| the following function. |
| |
| #include <isl/polynomial.h> |
| __isl_give isl_pw_qpolynomial * |
| isl_pw_qpolynomial_from_pw_aff( |
| __isl_take isl_pw_aff *pwaff); |
| |
| Piecewise expressions can be copied and freed using the following functions. |
| |
| #include <isl/aff.h> |
| __isl_give isl_pw_aff *isl_pw_aff_copy( |
| __isl_keep isl_pw_aff *pwaff); |
| __isl_null isl_pw_aff *isl_pw_aff_free( |
| __isl_take isl_pw_aff *pwaff); |
| __isl_give isl_pw_multi_aff *isl_pw_multi_aff_copy( |
| __isl_keep isl_pw_multi_aff *pma); |
| __isl_null isl_pw_multi_aff *isl_pw_multi_aff_free( |
| __isl_take isl_pw_multi_aff *pma); |
| |
| #include <isl/polynomial.h> |
| __isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_copy( |
| __isl_keep isl_pw_qpolynomial *pwqp); |
| __isl_null isl_pw_qpolynomial *isl_pw_qpolynomial_free( |
| __isl_take isl_pw_qpolynomial *pwqp); |
| __isl_give isl_pw_qpolynomial_fold * |
| isl_pw_qpolynomial_fold_copy( |
| __isl_keep isl_pw_qpolynomial_fold *pwf); |
| __isl_null isl_pw_qpolynomial_fold * |
| isl_pw_qpolynomial_fold_free( |
| __isl_take isl_pw_qpolynomial_fold *pwf); |
| |
| To iterate over the different cells of a piecewise expression, |
| use the following functions. |
| |
| #include <isl/aff.h> |
| isl_bool isl_pw_aff_is_empty(__isl_keep isl_pw_aff *pwaff); |
| int isl_pw_aff_n_piece(__isl_keep isl_pw_aff *pwaff); |
| isl_stat isl_pw_aff_foreach_piece( |
| __isl_keep isl_pw_aff *pwaff, |
| isl_stat (*fn)(__isl_take isl_set *set, |
| __isl_take isl_aff *aff, |
| void *user), void *user); |
| int isl_pw_multi_aff_n_piece( |
| __isl_keep isl_pw_multi_aff *pma); |
| isl_stat isl_pw_multi_aff_foreach_piece( |
| __isl_keep isl_pw_multi_aff *pma, |
| isl_stat (*fn)(__isl_take isl_set *set, |
| __isl_take isl_multi_aff *maff, |
| void *user), void *user); |
| |
| #include <isl/polynomial.h> |
| int isl_pw_qpolynomial_n_piece( |
| __isl_keep isl_pw_qpolynomial *pwqp); |
| isl_stat isl_pw_qpolynomial_foreach_piece( |
| __isl_keep isl_pw_qpolynomial *pwqp, |
| isl_stat (*fn)(__isl_take isl_set *set, |
| __isl_take isl_qpolynomial *qp, |
| void *user), void *user); |
| isl_stat isl_pw_qpolynomial_foreach_lifted_piece( |
| __isl_keep isl_pw_qpolynomial *pwqp, |
| isl_stat (*fn)(__isl_take isl_set *set, |
| __isl_take isl_qpolynomial *qp, |
| void *user), void *user); |
| int isl_pw_qpolynomial_fold_n_piece( |
| __isl_keep isl_pw_qpolynomial_fold *pwf); |
| isl_stat isl_pw_qpolynomial_fold_foreach_piece( |
| __isl_keep isl_pw_qpolynomial_fold *pwf, |
| isl_stat (*fn)(__isl_take isl_set *set, |
| __isl_take isl_qpolynomial_fold *fold, |
| void *user), void *user); |
| isl_stat isl_pw_qpolynomial_fold_foreach_lifted_piece( |
| __isl_keep isl_pw_qpolynomial_fold *pwf, |
| isl_stat (*fn)(__isl_take isl_set *set, |
| __isl_take isl_qpolynomial_fold *fold, |
| void *user), void *user); |
| |
| As usual, the function C<fn> should return C<isl_stat_ok> on success |
| and C<isl_stat_error> on failure. The difference between |
| C<isl_pw_qpolynomial_foreach_piece> and |
| C<isl_pw_qpolynomial_foreach_lifted_piece> is that |
| C<isl_pw_qpolynomial_foreach_lifted_piece> will first |
| compute unique representations for all existentially quantified |
| variables and then turn these existentially quantified variables |
| into extra set variables, adapting the associated quasipolynomial |
| accordingly. This means that the C<set> passed to C<fn> |
| will not have any existentially quantified variables, but that |
| the dimensions of the sets may be different for different |
| invocations of C<fn>. |
| Similarly for C<isl_pw_qpolynomial_fold_foreach_piece> |
| and C<isl_pw_qpolynomial_fold_foreach_lifted_piece>. |
| |
| A piecewise expression consisting of the expressions at a given |
| position of a piecewise multiple expression can be extracted |
| using the following function. |
| |
| #include <isl/aff.h> |
| __isl_give isl_pw_aff *isl_pw_multi_aff_get_pw_aff( |
| __isl_keep isl_pw_multi_aff *pma, int pos); |
| |
| These expressions can be replaced using the following function. |
| |
| #include <isl/aff.h> |
| __isl_give isl_pw_multi_aff *isl_pw_multi_aff_set_pw_aff( |
| __isl_take isl_pw_multi_aff *pma, unsigned pos, |
| __isl_take isl_pw_aff *pa); |
| |
| Note that there is a difference between C<isl_multi_pw_aff> and |
| C<isl_pw_multi_aff> objects. The first is a sequence of piecewise |
| affine expressions, while the second is a piecewise sequence |
| of affine expressions. In particular, each of the piecewise |
| affine expressions in an C<isl_multi_pw_aff> may have a different |
| domain, while all multiple expressions associated to a cell |
| in an C<isl_pw_multi_aff> have the same domain. |
| It is possible to convert between the two, but when converting |
| an C<isl_multi_pw_aff> to an C<isl_pw_multi_aff>, the domain |
| of the result is the intersection of the domains of the input. |
| The reverse conversion is exact. |
| |
| #include <isl/aff.h> |
| __isl_give isl_pw_multi_aff * |
| isl_pw_multi_aff_from_multi_pw_aff( |
| __isl_take isl_multi_pw_aff *mpa); |
| __isl_give isl_multi_pw_aff * |
| isl_multi_pw_aff_from_pw_multi_aff( |
| __isl_take isl_pw_multi_aff *pma); |
| |
| =head3 Union Expressions |
| |
| A union expression collects base expressions defined |
| over different domains. The space of a union expression |
| is that of the shared parameter space. |
| |
| The union expression types defined by C<isl> |
| are C<isl_union_pw_aff>, C<isl_union_pw_multi_aff>, |
| C<isl_union_pw_qpolynomial> and C<isl_union_pw_qpolynomial_fold>. |
| In case of |
| C<isl_union_pw_aff>, |
| C<isl_union_pw_qpolynomial> and C<isl_union_pw_qpolynomial_fold>, |
| there can be at most one base expression for a given domain space. |
| In case of |
| C<isl_union_pw_multi_aff>, |
| there can be multiple such expressions for a given domain space, |
| but the domains of these expressions need to be disjoint. |
| |
| An empty union expression can be created using the following functions. |
| |
| #include <isl/aff.h> |
| __isl_give isl_union_pw_aff *isl_union_pw_aff_empty( |
| __isl_take isl_space *space); |
| __isl_give isl_union_pw_multi_aff * |
| isl_union_pw_multi_aff_empty( |
| __isl_take isl_space *space); |
| |
| #include <isl/polynomial.h> |
| __isl_give isl_union_pw_qpolynomial * |
| isl_union_pw_qpolynomial_zero( |
| __isl_take isl_space *space); |
| |
| A union expression containing a single base expression |
| can be created using the following functions. |
| |
| #include <isl/aff.h> |
| __isl_give isl_union_pw_aff * |
| isl_union_pw_aff_from_pw_aff( |
| __isl_take isl_pw_aff *pa); |
| __isl_give isl_union_pw_multi_aff * |
| isl_union_pw_multi_aff_from_aff( |
| __isl_take isl_aff *aff); |
| __isl_give isl_union_pw_multi_aff * |
| isl_union_pw_multi_aff_from_pw_multi_aff( |
| __isl_take isl_pw_multi_aff *pma); |
| |
| #include <isl/polynomial.h> |
| __isl_give isl_union_pw_qpolynomial * |
| isl_union_pw_qpolynomial_from_pw_qpolynomial( |
| __isl_take isl_pw_qpolynomial *pwqp); |
| |
| The following functions create a base expression on each |
| of the sets in the union set and collect the results. |
| |
| #include <isl/aff.h> |
| __isl_give isl_union_pw_multi_aff * |
| isl_union_pw_multi_aff_from_union_pw_aff( |
| __isl_take isl_union_pw_aff *upa); |
| __isl_give isl_union_pw_aff * |
| isl_union_pw_multi_aff_get_union_pw_aff( |
| __isl_keep isl_union_pw_multi_aff *upma, int pos); |
| __isl_give isl_union_pw_aff * |
| isl_union_pw_aff_val_on_domain( |
| __isl_take isl_union_set *domain, |
| __isl_take isl_val *v); |
| __isl_give isl_union_pw_multi_aff * |
| isl_union_pw_multi_aff_multi_val_on_domain( |
| __isl_take isl_union_set *domain, |
| __isl_take isl_multi_val *mv); |
| __isl_give isl_union_pw_aff * |
| isl_union_pw_aff_param_on_domain_id( |
| __isl_take isl_union_set *domain, |
| __isl_take isl_id *id); |
| |
| The C<id> argument of C<isl_union_pw_aff_param_on_domain_id> |
| is the identifier of a parameter that may or may not already |
| be present in C<domain>. |
| |
| An C<isl_union_pw_aff> that is equal to a (parametric) affine |
| or piecewise affine |
| expression on a given domain can be created using the following |
| functions. |
| |
| #include <isl/aff.h> |
| __isl_give isl_union_pw_aff * |
| isl_union_pw_aff_aff_on_domain( |
| __isl_take isl_union_set *domain, |
| __isl_take isl_aff *aff); |
| __isl_give isl_union_pw_aff * |
| isl_union_pw_aff_pw_aff_on_domain( |
| __isl_take isl_union_set *domain, |
| __isl_take isl_pw_aff *pa); |
| |
| A base expression can be added to a union expression using |
| the following functions. |
| |
| #include <isl/aff.h> |
| __isl_give isl_union_pw_aff * |
| isl_union_pw_aff_add_pw_aff( |
| __isl_take isl_union_pw_aff *upa, |
| __isl_take isl_pw_aff *pa); |
| __isl_give isl_union_pw_multi_aff * |
| isl_union_pw_multi_aff_add_pw_multi_aff( |
| __isl_take isl_union_pw_multi_aff *upma, |
| __isl_take isl_pw_multi_aff *pma); |
| |
| #include <isl/polynomial.h> |
| __isl_give isl_union_pw_qpolynomial * |
| isl_union_pw_qpolynomial_add_pw_qpolynomial( |
| __isl_take isl_union_pw_qpolynomial *upwqp, |
| __isl_take isl_pw_qpolynomial *pwqp); |
| |
| Union expressions can be copied and freed using |
| the following functions. |
| |
| #include <isl/aff.h> |
| __isl_give isl_union_pw_aff *isl_union_pw_aff_copy( |
| __isl_keep isl_union_pw_aff *upa); |
| __isl_null isl_union_pw_aff *isl_union_pw_aff_free( |
| __isl_take isl_union_pw_aff *upa); |
| __isl_give isl_union_pw_multi_aff * |
| isl_union_pw_multi_aff_copy( |
| __isl_keep isl_union_pw_multi_aff *upma); |
| __isl_null isl_union_pw_multi_aff * |
| isl_union_pw_multi_aff_free( |
| __isl_take isl_union_pw_multi_aff *upma); |
| |
| #include <isl/polynomial.h> |
| __isl_give isl_union_pw_qpolynomial * |
| isl_union_pw_qpolynomial_copy( |
| __isl_keep isl_union_pw_qpolynomial *upwqp); |
| __isl_null isl_union_pw_qpolynomial * |
| isl_union_pw_qpolynomial_free( |
| __isl_take isl_union_pw_qpolynomial *upwqp); |
| __isl_give isl_union_pw_qpolynomial_fold * |
| isl_union_pw_qpolynomial_fold_copy( |
| __isl_keep isl_union_pw_qpolynomial_fold *upwf); |
| __isl_null isl_union_pw_qpolynomial_fold * |
| isl_union_pw_qpolynomial_fold_free( |
| __isl_take isl_union_pw_qpolynomial_fold *upwf); |
| |
| To iterate over the base expressions in a union expression, |
| use the following functions. |
| |
| #include <isl/aff.h> |
| int isl_union_pw_aff_n_pw_aff( |
| __isl_keep isl_union_pw_aff *upa); |
| isl_stat isl_union_pw_aff_foreach_pw_aff( |
| __isl_keep isl_union_pw_aff *upa, |
| isl_stat (*fn)(__isl_take isl_pw_aff *pa, |
| void *user), void *user); |
| int isl_union_pw_multi_aff_n_pw_multi_aff( |
| __isl_keep isl_union_pw_multi_aff *upma); |
| isl_stat isl_union_pw_multi_aff_foreach_pw_multi_aff( |
| __isl_keep isl_union_pw_multi_aff *upma, |
| isl_stat (*fn)(__isl_take isl_pw_multi_aff *pma, |
| void *user), void *user); |
| |
| #include <isl/polynomial.h> |
| int isl_union_pw_qpolynomial_n_pw_qpolynomial( |
| __isl_keep isl_union_pw_qpolynomial *upwqp); |
| isl_stat isl_union_pw_qpolynomial_foreach_pw_qpolynomial( |
| __isl_keep isl_union_pw_qpolynomial *upwqp, |
| isl_stat (*fn)(__isl_take isl_pw_qpolynomial *pwqp, |
| void *user), void *user); |
| int isl_union_pw_qpolynomial_fold_n_pw_qpolynomial_fold( |
| __isl_keep isl_union_pw_qpolynomial_fold *upwf); |
| isl_stat isl_union_pw_qpolynomial_fold_foreach_pw_qpolynomial_fold( |
| __isl_keep isl_union_pw_qpolynomial_fold *upwf, |
| isl_stat (*fn)(__isl_take isl_pw_qpolynomial_fold *pwf, |
| void *user), void *user); |
| |
| To extract the base expression in a given space from a union, use |
| the following functions. |
| |
| #include <isl/aff.h> |
| __isl_give isl_pw_aff *isl_union_pw_aff_extract_pw_aff( |
| __isl_keep isl_union_pw_aff *upa, |
| __isl_take isl_space *space); |
| __isl_give isl_pw_multi_aff * |
| isl_union_pw_multi_aff_extract_pw_multi_aff( |
| __isl_keep isl_union_pw_multi_aff *upma, |
| __isl_take isl_space *space); |
| |
| #include <isl/polynomial.h> |
| __isl_give isl_pw_qpolynomial * |
| isl_union_pw_qpolynomial_extract_pw_qpolynomial( |
| __isl_keep isl_union_pw_qpolynomial *upwqp, |
| __isl_take isl_space *space); |
| |
| It is also possible to obtain a list of the base expressions using |
| the following functions. |
| |
| #include <isl/aff.h> |
| __isl_give isl_pw_aff_list * |
| isl_union_pw_aff_get_pw_aff_list( |
| __isl_keep isl_union_pw_aff *upa); |
| __isl_give isl_pw_multi_aff_list * |
| isl_union_pw_multi_aff_get_pw_multi_aff_list( |
| __isl_keep isl_union_pw_multi_aff *upma); |
| |
| #include <isl/polynomial.h> |
| __isl_give isl_pw_qpolynomial_list * |
| isl_union_pw_qpolynomial_get_pw_qpolynomial_list( |
| __isl_keep isl_union_pw_qpolynomial *upwqp); |
| __isl_give isl_pw_qpolynomial_fold_list * |
| isl_union_pw_qpolynomial_fold_get_pw_qpolynomial_fold_list( |
| __isl_keep isl_union_pw_qpolynomial_fold *upwf); |
| |
| The returned list can be manipulated using the functions in L<"Lists">. |
| |
| =head2 Input and Output |
| |
| For set and relation, |
| C<isl> supports its own input/output format, which is similar |
| to the C<Omega> format, but also supports the C<PolyLib> format |
| in some cases. |
| For other object types, typically only an C<isl> format is supported. |
| |
| =head3 C<isl> format |
| |
| The C<isl> format is similar to that of C<Omega>, but has a different |
| syntax for describing the parameters and allows for the definition |
| of an existentially quantified variable as the integer division |
| of an affine expression. |
| For example, the set of integers C<i> between C<0> and C<n> |
| such that C<i % 10 <= 6> can be described as |
| |
| [n] -> { [i] : exists (a = [i/10] : 0 <= i and i <= n and |
| i - 10 a <= 6) } |
| |
| A set or relation can have several disjuncts, separated |
| by the keyword C<or>. Each disjunct is either a conjunction |
| of constraints or a projection (C<exists>) of a conjunction |
| of constraints. The constraints are separated by the keyword |
| C<and>. |
| |
| =head3 C<PolyLib> format |
| |
| If the represented set is a union, then the first line |
| contains a single number representing the number of disjuncts. |
| Otherwise, a line containing the number C<1> is optional. |
| |
| Each disjunct is represented by a matrix of constraints. |
| The first line contains two numbers representing |
| the number of rows and columns, |
| where the number of rows is equal to the number of constraints |
| and the number of columns is equal to two plus the number of variables. |
| The following lines contain the actual rows of the constraint matrix. |
| In each row, the first column indicates whether the constraint |
| is an equality (C<0>) or inequality (C<1>). The final column |
| corresponds to the constant term. |
| |
| If the set is parametric, then the coefficients of the parameters |
| appear in the last columns before the constant column. |
| The coefficients of any existentially quantified variables appear |
| between those of the set variables and those of the parameters. |
| |
| =head3 Extended C<PolyLib> format |
| |
| The extended C<PolyLib> format is nearly identical to the |
| C<PolyLib> format. The only difference is that the line |
| containing the number of rows and columns of a constraint matrix |
| also contains four additional numbers: |
| the number of output dimensions, the number of input dimensions, |
| the number of local dimensions (i.e., the number of existentially |
| quantified variables) and the number of parameters. |
| For sets, the number of ``output'' dimensions is equal |
| to the number of set dimensions, while the number of ``input'' |
| dimensions is zero. |
| |
| =head3 Input |
| |
| Objects can be read from input using the following functions. |
| |
| #include <isl/val.h> |
| __isl_give isl_val *isl_val_read_from_str(isl_ctx *ctx, |
| const char *str); |
| __isl_give isl_multi_val *isl_multi_val_read_from_str( |
| isl_ctx *ctx, const char *str); |
| |
| #include <isl/set.h> |
| __isl_give isl_basic_set *isl_basic_set_read_from_file( |
| isl_ctx *ctx, FILE *input); |
| __isl_give isl_basic_set *isl_basic_set_read_from_str( |
| isl_ctx *ctx, const char *str); |
| __isl_give isl_set *isl_set_read_from_file(isl_ctx *ctx, |
| FILE *input); |
| __isl_give isl_set *isl_set_read_from_str(isl_ctx *ctx, |
| const char *str); |
| |
| #include <isl/map.h> |
| __isl_give isl_basic_map *isl_basic_map_read_from_file( |
| isl_ctx *ctx, FILE *input); |
| __isl_give isl_basic_map *isl_basic_map_read_from_str( |
| isl_ctx *ctx, const char *str); |
| __isl_give isl_map *isl_map_read_from_file( |
| isl_ctx *ctx, FILE *input); |
| __isl_give isl_map *isl_map_read_from_str(isl_ctx *ctx, |
| const char *str); |
| |
| #include <isl/union_set.h> |
| __isl_give isl_union_set *isl_union_set_read_from_file( |
| isl_ctx *ctx, FILE *input); |
| __isl_give isl_union_set *isl_union_set_read_from_str( |
| isl_ctx *ctx, const char *str); |
| |
| #include <isl/union_map.h> |
| __isl_give isl_union_map *isl_union_map_read_from_file( |
| isl_ctx *ctx, FILE *input); |
| __isl_give isl_union_map *isl_union_map_read_from_str( |
| isl_ctx *ctx, const char *str); |
| |
| #include <isl/aff.h> |
| __isl_give isl_aff *isl_aff_read_from_str( |
| isl_ctx *ctx, const char *str); |
| __isl_give isl_multi_aff *isl_multi_aff_read_from_str( |
| isl_ctx *ctx, const char *str); |
| __isl_give isl_pw_aff *isl_pw_aff_read_from_str( |
| isl_ctx *ctx, const char *str); |
| __isl_give isl_pw_multi_aff *isl_pw_multi_aff_read_from_str( |
| isl_ctx *ctx, const char *str); |
| __isl_give isl_multi_pw_aff *isl_multi_pw_aff_read_from_str( |
| isl_ctx *ctx, const char *str); |
| __isl_give isl_union_pw_aff * |
| isl_union_pw_aff_read_from_str( |
| isl_ctx *ctx, const char *str); |
| __isl_give isl_union_pw_multi_aff * |
| isl_union_pw_multi_aff_read_from_str( |
| isl_ctx *ctx, const char *str); |
| __isl_give isl_multi_union_pw_aff * |
| isl_multi_union_pw_aff_read_from_str( |
| isl_ctx *ctx, const char *str); |
| |
| #include <isl/polynomial.h> |
| __isl_give isl_union_pw_qpolynomial * |
| isl_union_pw_qpolynomial_read_from_str( |
| isl_ctx *ctx, const char *str); |
| |
| For sets and relations, |
| the input format is autodetected and may be either the C<PolyLib> format |
| or the C<isl> format. |
| |
| =head3 Output |
| |
| Before anything can be printed, an C<isl_printer> needs to |
| be created. |
| |
| __isl_give isl_printer *isl_printer_to_file(isl_ctx *ctx, |
| FILE *file); |
| __isl_give isl_printer *isl_printer_to_str(isl_ctx *ctx); |
| __isl_null isl_printer *isl_printer_free( |
| __isl_take isl_printer *printer); |
| |
| C<isl_printer_to_file> prints to the given file, while |
| C<isl_printer_to_str> prints to a string that can be extracted |
| using the following function. |
| |
| #include <isl/printer.h> |
| __isl_give char *isl_printer_get_str( |
| __isl_keep isl_printer *printer); |
| |
| The printer can be inspected using the following functions. |
| |
| FILE *isl_printer_get_file( |
| __isl_keep isl_printer *printer); |
| int isl_printer_get_output_format( |
| __isl_keep isl_printer *p); |
| int isl_printer_get_yaml_style(__isl_keep isl_printer *p); |
| |
| The behavior of the printer can be modified in various ways |
| |
| __isl_give isl_printer *isl_printer_set_output_format( |
| __isl_take isl_printer *p, int output_format); |
| __isl_give isl_printer *isl_printer_set_indent( |
| __isl_take isl_printer *p, int indent); |
| __isl_give isl_printer *isl_printer_set_indent_prefix( |
| __isl_take isl_printer *p, const char *prefix); |
| __isl_give isl_printer *isl_printer_indent( |
| __isl_take isl_printer *p, int indent); |
| __isl_give isl_printer *isl_printer_set_prefix( |
| __isl_take isl_printer *p, const char *prefix); |
| __isl_give isl_printer *isl_printer_set_suffix( |
| __isl_take isl_printer *p, const char *suffix); |
| __isl_give isl_printer *isl_printer_set_yaml_style( |
| __isl_take isl_printer *p, int yaml_style); |
| |
| The C<output_format> may be either C<ISL_FORMAT_ISL>, C<ISL_FORMAT_OMEGA>, |
| C<ISL_FORMAT_POLYLIB>, C<ISL_FORMAT_EXT_POLYLIB> or C<ISL_FORMAT_LATEX> |
| and defaults to C<ISL_FORMAT_ISL>. |
| Each line in the output is prefixed by C<indent_prefix>, |
| indented by C<indent> (set by C<isl_printer_set_indent>) spaces |
| (default: 0), prefixed by C<prefix> and suffixed by C<suffix>. |
| In the C<PolyLib> format output, |
| the coefficients of the existentially quantified variables |
| appear between those of the set variables and those |
| of the parameters. |
| The function C<isl_printer_indent> increases the indentation |
| by the specified amount (which may be negative). |
| The YAML style may be either C<ISL_YAML_STYLE_BLOCK> or |
| C<ISL_YAML_STYLE_FLOW> and when we are printing something |
| in YAML format. |
| |
| 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/val.h> |
| __isl_give isl_printer *isl_printer_print_val( |
| __isl_take isl_printer *p, __isl_keep isl_val *v); |
| |
| #include <isl/set.h> |
| __isl_give isl_printer *isl_printer_print_basic_set( |
| __isl_take isl_printer *printer, |
| __isl_keep isl_basic_set *bset); |
| __isl_give isl_printer *isl_printer_print_set( |
| __isl_take isl_printer *printer, |
| __isl_keep isl_set *set); |
| |
| #include <isl/map.h> |
| __isl_give isl_printer *isl_printer_print_basic_map( |
| __isl_take isl_printer *printer, |
| __isl_keep isl_basic_map *bmap); |
| __isl_give isl_printer *isl_printer_print_map( |
| __isl_take isl_printer *printer, |
| __isl_keep isl_map *map); |
| |
| #include <isl/union_set.h> |
| __isl_give isl_printer *isl_printer_print_union_set( |
| __isl_take isl_printer *p, |
| __isl_keep isl_union_set *uset); |
| |
| #include <isl/union_map.h> |
| __isl_give isl_printer *isl_printer_print_union_map( |
| __isl_take isl_printer *p, |
| __isl_keep isl_union_map *umap); |
| |
| #include <isl/val.h> |
| __isl_give isl_printer *isl_printer_print_multi_val( |
| __isl_take isl_printer *p, |
| __isl_keep isl_multi_val *mv); |
| |
| #include <isl/aff.h> |
| __isl_give isl_printer *isl_printer_print_aff( |
| __isl_take isl_printer *p, __isl_keep isl_aff *aff); |
| __isl_give isl_printer *isl_printer_print_multi_aff( |
| __isl_take isl_printer *p, |
| __isl_keep isl_multi_aff *maff); |
| __isl_give isl_printer *isl_printer_print_pw_aff( |
| __isl_take isl_printer *p, |
| __isl_keep isl_pw_aff *pwaff); |
| __isl_give isl_printer *isl_printer_print_pw_multi_aff( |
| __isl_take isl_printer *p, |
| __isl_keep isl_pw_multi_aff *pma); |
| __isl_give isl_printer *isl_printer_print_multi_pw_aff( |
| __isl_take isl_printer *p, |
| __isl_keep isl_multi_pw_aff *mpa); |
| __isl_give isl_printer *isl_printer_print_union_pw_aff( |
| __isl_take isl_printer *p, |
| __isl_keep isl_union_pw_aff *upa); |
| __isl_give isl_printer *isl_printer_print_union_pw_multi_aff( |
| __isl_take isl_printer *p, |
| __isl_keep isl_union_pw_multi_aff *upma); |
| __isl_give isl_printer * |
| isl_printer_print_multi_union_pw_aff( |
| __isl_take isl_printer *p, |
| __isl_keep isl_multi_union_pw_aff *mupa); |
| |
| #include <isl/polynomial.h> |
| __isl_give isl_printer *isl_printer_print_qpolynomial( |
| __isl_take isl_printer *p, |
| __isl_keep isl_qpolynomial *qp); |
| __isl_give isl_printer *isl_printer_print_pw_qpolynomial( |
| __isl_take isl_printer *p, |
| __isl_keep isl_pw_qpolynomial *pwqp); |
| __isl_give isl_printer *isl_printer_print_union_pw_qpolynomial( |
| __isl_take isl_printer *p, |
| __isl_keep isl_union_pw_qpolynomial *upwqp); |
| |
| __isl_give isl_printer * |
| isl_printer_print_pw_qpolynomial_fold( |
| __isl_take isl_printer *p, |
| __isl_keep isl_pw_qpolynomial_fold *pwf); |
| __isl_give isl_printer * |
| isl_printer_print_union_pw_qpolynomial_fold( |
| __isl_take isl_printer *p, |
| __isl_keep isl_union_pw_qpolynomial_fold *upwf); |
| |
| For C<isl_printer_print_qpolynomial>, |
| C<isl_printer_print_pw_qpolynomial> and |
| C<isl_printer_print_pw_qpolynomial_fold>, |
| the output format of the printer |
| needs to be set to either C<ISL_FORMAT_ISL> or C<ISL_FORMAT_C>. |
| For C<isl_printer_print_union_pw_qpolynomial> and |
| C<isl_printer_print_union_pw_qpolynomial_fold>, only C<ISL_FORMAT_ISL> |
| is supported. |
| In case of printing in C<ISL_FORMAT_C>, the user may want |
| to set the names of all dimensions first. |
| |
| C<isl> also provides limited support for printing YAML documents, |
| just enough for the internal use for printing such documents. |
| |
| #include <isl/printer.h> |
| __isl_give isl_printer *isl_printer_yaml_start_mapping( |
| __isl_take isl_printer *p); |
| __isl_give isl_printer *isl_printer_yaml_end_mapping( |
| __isl_take isl_printer *p); |
| __isl_give isl_printer *isl_printer_yaml_start_sequence( |
| __isl_take isl_printer *p); |
| __isl_give isl_printer *isl_printer_yaml_end_sequence( |
| __isl_take isl_printer *p); |
| __isl_give isl_printer *isl_printer_yaml_next( |
| __isl_take isl_printer *p); |
| |
| A document is started by a call to either |
| C<isl_printer_yaml_start_mapping> or C<isl_printer_yaml_start_sequence>. |
| Anything printed to the printer after such a call belong to the |
| first key of the mapping or the first element in the sequence. |
| The function C<isl_printer_yaml_next> moves to the value if |
| we are currently printing a mapping key, the next key if we |
| are printing a value or the next element if we are printing |
| an element in a sequence. |
| Nested mappings and sequences are initiated by the same |
| C<isl_printer_yaml_start_mapping> or C<isl_printer_yaml_start_sequence>. |
| Each call to these functions needs to have a corresponding call to |
| C<isl_printer_yaml_end_mapping> or C<isl_printer_yaml_end_sequence>. |
| |
| When called on a file printer, the following function flushes |
| the file. When called on a string printer, the buffer is cleared. |
| |
| __isl_give isl_printer *isl_printer_flush( |
| __isl_take isl_printer *p); |
| |
| The following functions allow the user to attach |
| notes to a printer in order to keep track of additional state. |
| |
| #include <isl/printer.h> |
| isl_bool isl_printer_has_note(__isl_keep isl_printer *p, |
| __isl_keep isl_id *id); |
| __isl_give isl_id *isl_printer_get_note( |
| __isl_keep isl_printer *p, __isl_take isl_id *id); |
| __isl_give isl_printer *isl_printer_set_note( |
| __isl_take isl_printer *p, |
| __isl_take isl_id *id, __isl_take isl_id *note); |
| |
| C<isl_printer_set_note> associates the given note to the given |
| identifier in the printer. |
| C<isl_printer_get_note> retrieves a note associated to an |
| identifier, while |
| C<isl_printer_has_note> checks if there is such a note. |
| C<isl_printer_get_note> fails if the requested note does not exist. |
| |
| Alternatively, a string representation can be obtained |
| directly using the following functions, which always print |
| in isl format. |
| |
| #include <isl/id.h> |
| __isl_give char *isl_id_to_str( |
| __isl_keep isl_id *id); |
| |
| #include <isl/space.h> |
| __isl_give char *isl_space_to_str( |
| __isl_keep isl_space *space); |
| |
| #include <isl/val.h> |
| __isl_give char *isl_val_to_str(__isl_keep isl_val *v); |
| __isl_give char *isl_multi_val_to_str( |
| __isl_keep isl_multi_val *mv); |
| |
| #include <isl/set.h> |
| __isl_give char *isl_basic_set_to_str( |
| __isl_keep isl_basic_set *bset); |
| __isl_give char *isl_set_to_str( |
| __isl_keep isl_set *set); |
| |
| #include <isl/union_set.h> |
| __isl_give char *isl_union_set_to_str( |
| __isl_keep isl_union_set *uset); |
| |
| #include <isl/map.h> |
| __isl_give char *isl_basic_map_to_str( |
| __isl_keep isl_basic_map *bmap); |
| __isl_give char *isl_map_to_str( |
| __isl_keep isl_map *map); |
| |
| #include <isl/union_map.h> |
| __isl_give char *isl_union_map_to_str( |
| __isl_keep isl_union_map *umap); |
| |
| #include <isl/aff.h> |
| __isl_give char *isl_aff_to_str(__isl_keep isl_aff *aff); |
| __isl_give char *isl_pw_aff_to_str( |
| __isl_keep isl_pw_aff *pa); |
| __isl_give char *isl_multi_aff_to_str( |
| __isl_keep isl_multi_aff *ma); |
| __isl_give char *isl_pw_multi_aff_to_str( |
| __isl_keep isl_pw_multi_aff *pma); |
| __isl_give char *isl_multi_pw_aff_to_str( |
| __isl_keep isl_multi_pw_aff *mpa); |
| __isl_give char *isl_union_pw_aff_to_str( |
| __isl_keep isl_union_pw_aff *upa); |
| __isl_give char *isl_union_pw_multi_aff_to_str( |
| __isl_keep isl_union_pw_multi_aff *upma); |
| __isl_give char *isl_multi_union_pw_aff_to_str( |
| __isl_keep isl_multi_union_pw_aff *mupa); |
| |
| #include <isl/point.h> |
| __isl_give char *isl_point_to_str( |
| __isl_keep isl_point *pnt); |
| |
| #include <isl/polynomial.h> |
| __isl_give char *isl_pw_qpolynomial_to_str( |
| __isl_keep isl_pw_qpolynomial *pwqp); |
| __isl_give char *isl_union_pw_qpolynomial_to_str( |
| __isl_keep isl_union_pw_qpolynomial *upwqp); |
| |
| =head2 Properties |
| |
| =head3 Unary Properties |
| |
| =over |
| |
| =item * Emptiness |
| |
| The following functions test whether the given set or relation |
| contains any integer points. The ``plain'' variants do not perform |
| any computations, but simply check if the given set or relation |
| is already known to be empty. |
| |
| #include <isl/set.h> |
| isl_bool isl_basic_set_plain_is_empty( |
| __isl_keep isl_basic_set *bset); |
| isl_bool isl_basic_set_is_empty( |
| __isl_keep isl_basic_set *bset); |
| isl_bool isl_set_plain_is_empty( |
| __isl_keep isl_set *set); |
| isl_bool isl_set_is_empty(__isl_keep isl_set *set); |
| |
| #include <isl/union_set.h> |
| isl_bool isl_union_set_is_empty( |
| __isl_keep isl_union_set *uset); |
| |
| #include <isl/map.h> |
| isl_bool isl_basic_map_plain_is_empty( |
| __isl_keep isl_basic_map *bmap); |
| isl_bool isl_basic_map_is_empty( |
| __isl_keep isl_basic_map *bmap); |
| isl_bool isl_map_plain_is_empty( |
| __isl_keep isl_map *map); |
| isl_bool isl_map_is_empty(__isl_keep isl_map *map); |
| |
| #include <isl/union_map.h> |
| isl_bool isl_union_map_plain_is_empty( |
| __isl_keep isl_union_map *umap); |
| isl_bool isl_union_map_is_empty( |
| __isl_keep isl_union_map *umap); |
| |
| =item * Universality |
| |
| isl_bool isl_basic_set_plain_is_universe( |
| __isl_keep isl_basic_set *bset); |
| isl_bool isl_basic_set_is_universe( |
| __isl_keep isl_basic_set *bset); |
| isl_bool isl_basic_map_plain_is_universe( |
| __isl_keep isl_basic_map *bmap); |
| isl_bool isl_basic_map_is_universe( |
| __isl_keep isl_basic_map *bmap); |
| isl_bool isl_set_plain_is_universe( |
| __isl_keep isl_set *set); |
| isl_bool isl_map_plain_is_universe( |
| __isl_keep isl_map *map); |
| |
| =item * Single-valuedness |
| |
| #include <isl/set.h> |
| isl_bool isl_set_is_singleton(__isl_keep isl_set *set); |
| |
| #include <isl/map.h> |
| isl_bool isl_basic_map_is_single_valued( |
| __isl_keep isl_basic_map *bmap); |
| isl_bool isl_map_plain_is_single_valued( |
| __isl_keep isl_map *map); |
| isl_bool isl_map_is_single_valued(__isl_keep isl_map *map); |
| |
| #include <isl/union_map.h> |
| isl_bool isl_union_map_is_single_valued( |
| __isl_keep isl_union_map *umap); |
| |
| =item * Injectivity |
| |
| isl_bool isl_map_plain_is_injective( |
| __isl_keep isl_map *map); |
| isl_bool isl_map_is_injective( |
| __isl_keep isl_map *map); |
| isl_bool isl_union_map_plain_is_injective( |
| __isl_keep isl_union_map *umap); |
| isl_bool isl_union_map_is_injective( |
| __isl_keep isl_union_map *umap); |
| |
| =item * Bijectivity |
| |
| isl_bool isl_map_is_bijective( |
| __isl_keep isl_map *map); |
| isl_bool isl_union_map_is_bijective( |
| __isl_keep isl_union_map *umap); |
| |
| =item * Identity |
| |
| The following functions test whether the given relation |
| only maps elements to themselves. |
| |
| #include <isl/map.h> |
| isl_bool isl_map_is_identity( |
| __isl_keep isl_map *map); |
| |
| #include <isl/union_map.h> |
| isl_bool isl_union_map_is_identity( |
| __isl_keep isl_union_map *umap); |
| |
| =item * Position |
| |
| __isl_give isl_val * |
| isl_basic_map_plain_get_val_if_fixed( |
| __isl_keep isl_basic_map *bmap, |
| enum isl_dim_type type, unsigned pos); |
| __isl_give isl_val *isl_set_plain_get_val_if_fixed( |
| __isl_keep isl_set *set, |
| enum isl_dim_type type, unsigned pos); |
| __isl_give isl_val *isl_map_plain_get_val_if_fixed( |
| __isl_keep isl_map *map, |
| enum isl_dim_type type, unsigned pos); |
| |
| If the set or relation obviously lies on a hyperplane where the given dimension |
| has a fixed value, then return that value. |
| Otherwise return NaN. |
| |
| =item * Stride |
| |
| isl_stat isl_set_dim_residue_class_val( |
| __isl_keep isl_set *set, |
| int pos, __isl_give isl_val **modulo, |
| __isl_give isl_val **residue); |
| |
| Check if the values of the given set dimension are equal to a fixed |
| value modulo some integer value. If so, assign the modulo to C<*modulo> |
| and the fixed value to C<*residue>. If the given dimension attains only |
| a single value, then assign C<0> to C<*modulo> and the fixed value to |
| C<*residue>. |
| If the dimension does not attain only a single value and if no modulo |
| can be found then assign C<1> to C<*modulo> and C<1> to C<*residue>. |
| |
| #include <isl/set.h> |
| __isl_give isl_stride_info *isl_set_get_stride_info( |
| __isl_keep isl_set *set, int pos); |
| __isl_give isl_val *isl_set_get_stride( |
| __isl_keep isl_set *set, int pos); |
| |
| #include <isl/map.h> |
| __isl_give isl_stride_info * |
| isl_map_get_range_stride_info( |
| __isl_keep isl_map *map, int pos); |
| |
| Check if the values of the given set dimension are equal to |
| some affine expression of the other dimensions (the offset) |
| modulo some integer stride or |
| check if the values of the given output dimensions are equal to |
| some affine expression of the input dimensions (the offset) |
| modulo some integer stride. |
| If no more specific information can be found, then the stride |
| is taken to be one and the offset is taken to be the zero expression. |
| The function C<isl_set_get_stride> performs the same |
| computation as C<isl_set_get_stride_info> but only returns the stride. |
| For the other functions, |
| the stride and offset can be extracted from the returned object |
| using the following functions. |
| |
| #include <isl/stride_info.h> |
| __isl_give isl_val *isl_stride_info_get_stride( |
| __isl_keep isl_stride_info *si); |
| __isl_give isl_aff *isl_stride_info_get_offset( |
| __isl_keep isl_stride_info *si); |
| |
| The stride info object can be copied and released using the following |
| functions. |
| |
| #include <isl/stride_info.h> |
| __isl_give isl_stride_info *isl_stride_info_copy( |
| __isl_keep isl_stride_info *si); |
| __isl_null isl_stride_info *isl_stride_info_free( |
| __isl_take isl_stride_info *si); |
| |
| =item * Dependence |
| |
| To check whether the description of a set, relation or function depends |
| on one or more given dimensions, |
| the following functions can be used. |
| |
| #include <isl/constraint.h> |
| isl_bool isl_constraint_involves_dims( |
| __isl_keep isl_constraint *constraint, |
| enum isl_dim_type type, unsigned first, unsigned n); |
| |
| #include <isl/set.h> |
| isl_bool isl_basic_set_involves_dims( |
| __isl_keep isl_basic_set *bset, |
| enum isl_dim_type type, unsigned first, unsigned n); |
| isl_bool isl_set_involves_dims(__isl_keep isl_set *set, |
| enum isl_dim_type type, unsigned first, unsigned n); |
| |
| #include <isl/map.h> |
| isl_bool isl_basic_map_involves_dims( |
| __isl_keep isl_basic_map *bmap, |
| enum isl_dim_type type, unsigned first, unsigned n); |
| isl_bool isl_map_involves_dims(__isl_keep isl_map *map, |
| enum isl_dim_type type, unsigned first, unsigned n); |
| |
| #include <isl/union_map.h> |
| isl_bool isl_union_map_involves_dims( |
| __isl_keep isl_union_map *umap, |
| enum isl_dim_type type, unsigned first, unsigned n); |
| |
| #include <isl/aff.h> |
| isl_bool isl_aff_involves_dims(__isl_keep isl_aff *aff, |
| enum isl_dim_type type, unsigned first, unsigned n); |
| isl_bool isl_pw_aff_involves_dims( |
| __isl_keep isl_pw_aff *pwaff, |
| enum isl_dim_type type, unsigned first, unsigned n); |
| isl_bool isl_multi_aff_involves_dims( |
| __isl_keep isl_multi_aff *ma, |
| enum isl_dim_type type, unsigned first, unsigned n); |
| isl_bool isl_pw_multi_aff_involves_dims( |
| __isl_keep isl_pw_multi_aff *pma, |
| enum isl_dim_type type, unsigned first, unsigned n); |
| isl_bool isl_multi_pw_aff_involves_dims( |
| __isl_keep isl_multi_pw_aff *mpa, |
| enum isl_dim_type type, unsigned first, unsigned n); |
| |
| #include <isl/polynomial.h> |
| isl_bool isl_qpolynomial_involves_dims( |
| __isl_keep isl_qpolynomial *qp, |
| enum isl_dim_type type, unsigned first, unsigned n); |
| |
| Similarly, the following functions can be used to check whether |
| a given dimension is involved in any lower or upper bound. |
| |
| #include <isl/set.h> |
| isl_bool isl_set_dim_has_any_lower_bound( |
| __isl_keep isl_set *set, |
| enum isl_dim_type type, unsigned pos); |
| isl_bool isl_set_dim_has_any_upper_bound( |
| __isl_keep isl_set *set, |
| enum isl_dim_type type, unsigned pos); |
| |
| Note that these functions return true even if there is a bound on |
| the dimension on only some of the basic sets of C<set>. |
| To check if they have a bound for all of the basic sets in C<set>, |
| use the following functions instead. |
| |
| #include <isl/set.h> |
| isl_bool isl_set_dim_has_lower_bound( |
| __isl_keep isl_set *set, |
| enum isl_dim_type type, unsigned pos); |
| isl_bool isl_set_dim_has_upper_bound( |
| __isl_keep isl_set *set, |
| enum isl_dim_type type, unsigned pos); |
| |
| =item * Space |
| |
| To check whether a set is a parameter domain, use this function: |
| |
| isl_bool isl_set_is_params(__isl_keep isl_set *set); |
| isl_bool isl_union_set_is_params( |
| __isl_keep isl_union_set *uset); |
| |
| =item * Wrapping |
| |
| The following functions check whether the space of the given |
| (basic) set or relation domain and/or range is a wrapped relation. |
| |
| #include <isl/space.h> |
| isl_bool isl_space_is_wrapping( |
| __isl_keep isl_space *space); |
| isl_bool isl_space_domain_is_wrapping( |
| __isl_keep isl_space *space); |
| isl_bool isl_space_range_is_wrapping( |
| __isl_keep isl_space *space); |
| isl_bool isl_space_is_product( |
| __isl_keep isl_space *space); |
| |
| #include <isl/set.h> |
| isl_bool isl_basic_set_is_wrapping( |
| __isl_keep isl_basic_set *bset); |
| isl_bool isl_set_is_wrapping(__isl_keep isl_set *set); |
| |
| #include <isl/map.h> |
| isl_bool isl_map_domain_is_wrapping( |
| __isl_keep isl_map *map); |
| isl_bool isl_map_range_is_wrapping( |
| __isl_keep isl_map *map); |
| isl_bool isl_map_is_product(__isl_keep isl_map *map); |
| |
| #include <isl/val.h> |
| isl_bool isl_multi_val_range_is_wrapping( |
| __isl_keep isl_multi_val *mv); |
| |
| #include <isl/aff.h> |
| isl_bool isl_multi_aff_range_is_wrapping( |
| __isl_keep isl_multi_aff *ma); |
| isl_bool isl_multi_pw_aff_range_is_wrapping( |
| __isl_keep isl_multi_pw_aff *mpa); |
| isl_bool isl_multi_union_pw_aff_range_is_wrapping( |
| __isl_keep isl_multi_union_pw_aff *mupa); |
| |
| The input to C<isl_space_is_wrapping> should |
| be the space of a set, while that of |
| C<isl_space_domain_is_wrapping> and |
| C<isl_space_range_is_wrapping> should be the space of a relation. |
| The input to C<isl_space_is_product> can be either the space |
| of a set or that of a binary relation. |
| In case the input is the space of a binary relation, it checks |
| whether both domain and range are wrapping. |
| |
| =item * Internal Product |
| |
| isl_bool isl_basic_map_can_zip( |
| __isl_keep isl_basic_map *bmap); |
| isl_bool isl_map_can_zip(__isl_keep isl_map *map); |
| |
| Check whether the product of domain and range of the given relation |
| can be computed, |
| i.e., whether both domain and range are nested relations. |
| |
| =item * Currying |
| |
| #include <isl/space.h> |
| isl_bool isl_space_can_curry( |
| __isl_keep isl_space *space); |
| |
| #include <isl/map.h> |
| isl_bool isl_basic_map_can_curry( |
| __isl_keep isl_basic_map *bmap); |
| isl_bool isl_map_can_curry(__isl_keep isl_map *map); |
| |
| Check whether the domain of the (basic) relation is a wrapped relation. |
| |
| #include <isl/space.h> |
| __isl_give isl_space *isl_space_uncurry( |
| __isl_take isl_space *space); |
| |
| #include <isl/map.h> |
| isl_bool isl_basic_map_can_uncurry( |
| __isl_keep isl_basic_map *bmap); |
| isl_bool isl_map_can_uncurry(__isl_keep isl_map *map); |
| |
| Check whether the range of the (basic) relation is a wrapped relation. |
| |
| #include <isl/space.h> |
| isl_bool isl_space_can_range_curry( |
| __isl_keep isl_space *space); |
| |
| #include <isl/map.h> |
| isl_bool isl_map_can_range_curry( |
| __isl_keep isl_map *map); |
| |
| Check whether the domain of the relation wrapped in the range of |
| the input is itself a wrapped relation. |
| |
| =item * Special Values |
| |
| #include <isl/aff.h> |
| isl_bool isl_aff_is_cst(__isl_keep isl_aff *aff); |
| isl_bool isl_pw_aff_is_cst(__isl_keep isl_pw_aff *pwaff); |
| isl_bool isl_multi_pw_aff_is_cst( |
| __isl_keep isl_multi_pw_aff *mpa); |
| |
| Check whether the given expression is a constant. |
| |
| #include <isl/val.h> |
| isl_bool isl_multi_val_involves_nan( |
| __isl_keep isl_multi_val *mv); |
| |
| #include <isl/aff.h> |
| isl_bool isl_aff_is_nan(__isl_keep isl_aff *aff); |
| isl_bool isl_multi_aff_involves_nan( |
| __isl_keep isl_multi_aff *ma); |
| isl_bool isl_pw_aff_involves_nan( |
| __isl_keep isl_pw_aff *pa); |
| isl_bool isl_pw_multi_aff_involves_nan( |
| __isl_keep isl_pw_multi_aff *pma); |
| isl_bool isl_multi_pw_aff_involves_nan( |
| __isl_keep isl_multi_pw_aff *mpa); |
| isl_bool isl_union_pw_aff_involves_nan( |
| __isl_keep isl_union_pw_aff *upa); |
| isl_bool isl_union_pw_multi_aff_involves_nan( |
| __isl_keep isl_union_pw_multi_aff *upma); |
| isl_bool isl_multi_union_pw_aff_involves_nan( |
| __isl_keep isl_multi_union_pw_aff *mupa); |
| |
| #include <isl/polynomial.h> |
| isl_bool isl_qpolynomial_is_nan( |
| __isl_keep isl_qpolynomial *qp); |
| isl_bool isl_qpolynomial_fold_is_nan( |
| __isl_keep isl_qpolynomial_fold *fold); |
| isl_bool isl_pw_qpolynomial_involves_nan( |
| __isl_keep isl_pw_qpolynomial *pwqp); |
| isl_bool isl_pw_qpolynomial_fold_involves_nan( |
| __isl_keep isl_pw_qpolynomial_fold *pwf); |
| isl_bool isl_union_pw_qpolynomial_involves_nan( |
| __isl_keep isl_union_pw_qpolynomial *upwqp); |
| isl_bool isl_union_pw_qpolynomial_fold_involves_nan( |
| __isl_keep isl_union_pw_qpolynomial_fold *upwf); |
| |
| Check whether the given expression is equal to or involves NaN. |
| |
| #include <isl/aff.h> |
| isl_bool isl_aff_plain_is_zero( |
| __isl_keep isl_aff *aff); |
| |
| Check whether the affine expression is obviously zero. |
| |
| =back |
| |
| =head3 Binary Properties |
| |
| =over |
| |
| =item * Equality |
| |
| The following functions check whether two objects |
| represent the same set, relation or function. |
| The C<plain> variants only return true if the objects |
| are obviously the same. That is, they may return false |
| even if the objects are the same, but they will never |
| return true if the objects are not the same. |
| |
| #include <isl/set.h> |
| isl_bool isl_basic_set_plain_is_equal( |
| __isl_keep isl_basic_set *bset1, |
| __isl_keep isl_basic_set *bset2); |
| isl_bool isl_basic_set_is_equal( |
| __isl_keep isl_basic_set *bset1, |
| __isl_keep isl_basic_set *bset2); |
| isl_bool isl_set_plain_is_equal( |
| __isl_keep isl_set *set1, |
| __isl_keep isl_set *set2); |
| isl_bool isl_set_is_equal(__isl_keep isl_set *set1, |
| __isl_keep isl_set *set2); |
| |
| #include <isl/map.h> |
| isl_bool isl_basic_map_is_equal( |
| __isl_keep isl_basic_map *bmap1, |
| __isl_keep isl_basic_map *bmap2); |
| isl_bool isl_map_is_equal(__isl_keep isl_map *map1, |
| __isl_keep isl_map *map2); |
| isl_bool isl_map_plain_is_equal( |
| __isl_keep isl_map *map1, |
| __isl_keep isl_map *map2); |
| |
| #include <isl/union_set.h> |
| isl_bool isl_union_set_is_equal( |
| __isl_keep isl_union_set *uset1, |
| __isl_keep isl_union_set *uset2); |
| |
| #include <isl/union_map.h> |
| isl_bool isl_union_map_is_equal( |
| __isl_keep isl_union_map *umap1, |
| __isl_keep isl_union_map *umap2); |
| |
| #include <isl/val.h> |
| isl_bool isl_multi_val_plain_is_equal( |
| __isl_keep isl_multi_val *mv1, |
| __isl_keep isl_multi_val *mv2); |
| |
| #include <isl/aff.h> |
| isl_bool isl_aff_plain_is_equal( |
| __isl_keep isl_aff *aff1, |
| __isl_keep isl_aff *aff2); |
| isl_bool isl_multi_aff_plain_is_equal( |
| __isl_keep isl_multi_aff *maff1, |
| __isl_keep isl_multi_aff *maff2); |
| isl_bool isl_pw_aff_plain_is_equal( |
| __isl_keep isl_pw_aff *pwaff1, |
| __isl_keep isl_pw_aff *pwaff2); |
| isl_bool isl_pw_aff_is_equal( |
| __isl_keep isl_pw_aff *pa1, |
| __isl_keep isl_pw_aff *pa2); |
| isl_bool isl_pw_multi_aff_plain_is_equal( |
| __isl_keep isl_pw_multi_aff *pma1, |
| __isl_keep isl_pw_multi_aff *pma2); |
| isl_bool isl_pw_multi_aff_is_equal( |
| __isl_keep isl_pw_multi_aff *pma1, |
| __isl_keep isl_pw_multi_aff *pma2); |
| isl_bool isl_multi_pw_aff_plain_is_equal( |
| __isl_keep isl_multi_pw_aff *mpa1, |
| __isl_keep isl_multi_pw_aff *mpa2); |
| isl_bool isl_multi_pw_aff_is_equal( |
| __isl_keep isl_multi_pw_aff *mpa1, |
| __isl_keep isl_multi_pw_aff *mpa2); |
| isl_bool isl_union_pw_aff_plain_is_equal( |
| __isl_keep isl_union_pw_aff *upa1, |
| __isl_keep isl_union_pw_aff *upa2); |
| isl_bool isl_union_pw_multi_aff_plain_is_equal( |
| __isl_keep isl_union_pw_multi_aff *upma1, |
| __isl_keep isl_union_pw_multi_aff *upma2); |
| isl_bool isl_multi_union_pw_aff_plain_is_equal( |
| __isl_keep isl_multi_union_pw_aff *mupa1, |
| __isl_keep isl_multi_union_pw_aff *mupa2); |
| |
| #include <isl/polynomial.h> |
| isl_bool isl_union_pw_qpolynomial_plain_is_equal( |
| __isl_keep isl_union_pw_qpolynomial *upwqp1, |
| __isl_keep isl_union_pw_qpolynomial *upwqp2); |
| isl_bool isl_union_pw_qpolynomial_fold_plain_is_equal( |
| __isl_keep isl_union_pw_qpolynomial_fold *upwf1, |
| __isl_keep isl_union_pw_qpolynomial_fold *upwf2); |
| |
| =item * Disjointness |
| |
| #include <isl/set.h> |
| isl_bool isl_basic_set_is_disjoint( |
| __isl_keep isl_basic_set *bset1, |
| __isl_keep isl_basic_set *bset2); |
| isl_bool isl_set_plain_is_disjoint( |
| __isl_keep isl_set *set1, |
| __isl_keep isl_set *set2); |
| isl_bool isl_set_is_disjoint(__isl_keep isl_set *set1, |
| __isl_keep isl_set *set2); |
| |
| #include <isl/map.h> |
| isl_bool isl_basic_map_is_disjoint( |
| __isl_keep isl_basic_map *bmap1, |
| __isl_keep isl_basic_map *bmap2); |
| isl_bool isl_map_is_disjoint(__isl_keep isl_map *map1, |
| __isl_keep isl_map *map2); |
| |
| #include <isl/union_set.h> |
| isl_bool isl_union_set_is_disjoint( |
| __isl_keep isl_union_set *uset1, |
| __isl_keep isl_union_set *uset2); |
| |
| #include <isl/union_map.h> |
| isl_bool isl_union_map_is_disjoint( |
| __isl_keep isl_union_map *umap1, |
| __isl_keep isl_union_map *umap2); |
| |
| =item * Subset |
| |
| isl_bool isl_basic_set_is_subset( |
| __isl_keep isl_basic_set *bset1, |
| __isl_keep isl_basic_set *bset2); |
| isl_bool isl_set_is_subset(__isl_keep isl_set *set1, |
| __isl_keep isl_set *set2); |
| isl_bool isl_set_is_strict_subset( |
| __isl_keep isl_set *set1, |
| __isl_keep isl_set *set2); |
| isl_bool isl_union_set_is_subset( |
| __isl_keep isl_union_set *uset1, |
| __isl_keep isl_union_set *uset2); |
| isl_bool isl_union_set_is_strict_subset( |
| __isl_keep isl_union_set *uset1, |
| __isl_keep isl_union_set *uset2); |
| isl_bool isl_basic_map_is_subset( |
| __isl_keep isl_basic_map *bmap1, |
| __isl_keep isl_basic_map *bmap2); |
| isl_bool isl_basic_map_is_strict_subset( |
| __isl_keep isl_basic_map *bmap1, |
| __isl_keep isl_basic_map *bmap2); |
| isl_bool isl_map_is_subset( |
| __isl_keep isl_map *map1, |
| __isl_keep isl_map *map2); |
| isl_bool isl_map_is_strict_subset( |
| __isl_keep isl_map *map1, |
| __isl_keep isl_map *map2); |
| isl_bool isl_union_map_is_subset( |
| __isl_keep isl_union_map *umap1, |
| __isl_keep isl_union_map *umap2); |
| isl_bool isl_union_map_is_strict_subset( |
| __isl_keep isl_union_map *umap1, |
| __isl_keep isl_union_map *umap2); |
| |
| Check whether the first argument is a (strict) subset of the |
| second argument. |
| |
| =item * Order |
| |
| Every comparison function returns a negative value if the first |
| argument is considered smaller than the second, a positive value |
| if the first argument is considered greater and zero if the two |
| constraints are considered the same by the comparison criterion. |
| |
| #include <isl/constraint.h> |
| int isl_constraint_plain_cmp( |
| __isl_keep isl_constraint *c1, |
| __isl_keep isl_constraint *c2); |
| |
| This function is useful for sorting C<isl_constraint>s. |
| The order depends on the internal representation of the inputs. |
| The order is fixed over different calls to the function (assuming |
| the internal representation of the inputs has not changed), but may |
| change over different versions of C<isl>. |
| |
| #include <isl/constraint.h> |
| int isl_constraint_cmp_last_non_zero( |
| __isl_keep isl_constraint *c1, |
| __isl_keep isl_constraint *c2); |
| |
| This function can be used to sort constraints that live in the same |
| local space. Constraints that involve ``earlier'' dimensions or |
| that have a smaller coefficient for the shared latest dimension |
| are considered smaller than other constraints. |
| This function only defines a B<partial> order. |
| |
| #include <isl/set.h> |
| int isl_set_plain_cmp(__isl_keep isl_set *set1, |
| __isl_keep isl_set *set2); |
| |
| This function is useful for sorting C<isl_set>s. |
| The order depends on the internal representation of the inputs. |
| The order is fixed over different calls to the function (assuming |
| the internal representation of the inputs has not changed), but may |
| change over different versions of C<isl>. |
| |
| #include <isl/aff.h> |
| int isl_multi_aff_plain_cmp( |
| __isl_keep isl_multi_aff *ma1, |
| __isl_keep isl_multi_aff *ma2); |
| int isl_pw_aff_plain_cmp(__isl_keep isl_pw_aff *pa1, |
| __isl_keep isl_pw_aff *pa2); |
| |
| The functions C<isl_multi_aff_plain_cmp> and |
| C<isl_pw_aff_plain_cmp> can be used to sort C<isl_multi_aff>s and |
| C<isl_pw_aff>s. The order is not strictly defined. |
| The current order sorts expressions that only involve |
| earlier dimensions before those that involve later dimensions. |
| |
| =back |
| |
| =head2 Unary Operations |
| |
| =over |
| |
| =item * Complement |
| |
| __isl_give isl_set *isl_set_complement( |
| __isl_take isl_set *set); |
| __isl_give isl_map *isl_map_complement( |
| __isl_take isl_map *map); |
| |
| =item * Inverse map |
| |
| #include <isl/space.h> |
| __isl_give isl_space *isl_space_reverse( |
| __isl_take isl_space *space); |
| |
| #include <isl/map.h> |
| __isl_give isl_basic_map *isl_basic_map_reverse( |
| __isl_take isl_basic_map *bmap); |
| __isl_give isl_map *isl_map_reverse( |
| __isl_take isl_map *map); |
| |
| #include <isl/union_map.h> |
| __isl_give isl_union_map *isl_union_map_reverse( |
| __isl_take isl_union_map *umap); |
| |
| =item * Projection |
| |
| #include <isl/space.h> |
| __isl_give isl_space *isl_space_domain( |
| __isl_take isl_space *space); |
| __isl_give isl_space *isl_space_range( |
| __isl_take isl_space *space); |
| __isl_give isl_space *isl_space_params( |
| __isl_take isl_space *space); |
| |
| #include <isl/local_space.h> |
| __isl_give isl_local_space *isl_local_space_domain( |
| __isl_take isl_local_space *ls); |
| __isl_give isl_local_space *isl_local_space_range( |
| __isl_take isl_local_space *ls); |
| |
| #include <isl/set.h> |
| __isl_give isl_basic_set *isl_basic_set_project_out( |
| __isl_take isl_basic_set *bset, |
| enum isl_dim_type type, unsigned first, unsigned n); |
| __isl_give isl_set *isl_set_project_out(__isl_take isl_set *set, |
| enum isl_dim_type type, unsigned first, unsigned n); |
| __isl_give isl_map *isl_set_project_onto_map( |
| __isl_take isl_set *set, |
| enum isl_dim_type type, unsigned first, |
| unsigned n); |
| __isl_give isl_basic_set *isl_basic_set_params( |
| __isl_take isl_basic_set *bset); |
| __isl_give isl_set *isl_set_params(__isl_take isl_set *set); |
| |
| The function C<isl_set_project_onto_map> returns a relation |
| that projects the input set onto the given set dimensions. |
| |
| #include <isl/map.h> |
| __isl_give isl_basic_map *isl_basic_map_project_out( |
| __isl_take isl_basic_map *bmap, |
| enum isl_dim_type type, unsigned first, unsigned n); |
| __isl_give isl_map *isl_map_project_out(__isl_take isl_map *map, |
| enum isl_dim_type type, unsigned first, unsigned n); |
| __isl_give isl_basic_set *isl_basic_map_domain( |
| __isl_take isl_basic_map *bmap); |
| __isl_give isl_basic_set *isl_basic_map_range( |
| __isl_take isl_basic_map *bmap); |
| __isl_give isl_set *isl_map_params(__isl_take isl_map *map); |
| __isl_give isl_set *isl_map_domain( |
| __isl_take isl_map *bmap); |
| __isl_give isl_set *isl_map_range( |
| __isl_take isl_map *map); |
| |
| #include <isl/union_set.h> |
| __isl_give isl_union_set *isl_union_set_project_out( |
| __isl_take isl_union_set *uset, |
| enum isl_dim_type type, |
| unsigned first, unsigned n); |
| __isl_give isl_set *isl_union_set_params( |
| __isl_take isl_union_set *uset); |
| |
| The function C<isl_union_set_project_out> can only project out |
| parameters. |
| |
| #include <isl/union_map.h> |
| __isl_give isl_union_map *isl_union_map_project_out( |
| __isl_take isl_union_map *umap, |
| enum isl_dim_type type, unsigned first, unsigned n); |
| __isl_give isl_union_map * |
| isl_union_map_project_out_all_params( |
| __isl_take isl_union_map *umap); |
| __isl_give isl_set *isl_union_map_params( |
| __isl_take isl_union_map *umap); |
| __isl_give isl_union_set *isl_union_map_domain( |
| __isl_take isl_union_map *umap); |
| __isl_give isl_union_set *isl_union_map_range( |
| __isl_take isl_union_map *umap); |
| |
| The function C<isl_union_map_project_out> can only project out |
| parameters. |
| |
| #include <isl/aff.h> |
| __isl_give isl_aff *isl_aff_project_domain_on_params( |
| __isl_take isl_aff *aff); |
| __isl_give isl_multi_aff * |
| isl_multi_aff_project_domain_on_params( |
| __isl_take isl_multi_aff *ma); |
| __isl_give isl_pw_aff * |
| isl_pw_aff_project_domain_on_params( |
| __isl_take isl_pw_aff *pa); |
| __isl_give isl_multi_pw_aff * |
| isl_multi_pw_aff_project_domain_on_params( |
| __isl_take isl_multi_pw_aff *mpa); |
| __isl_give isl_pw_multi_aff * |
| isl_pw_multi_aff_project_domain_on_params( |
| __isl_take isl_pw_multi_aff *pma); |
| __isl_give isl_set *isl_pw_aff_domain( |
| __isl_take isl_pw_aff *pwaff); |
| __isl_give isl_set *isl_pw_multi_aff_domain( |
| __isl_take isl_pw_multi_aff *pma); |
| __isl_give isl_set *isl_multi_pw_aff_domain( |
| __isl_take isl_multi_pw_aff *mpa); |
| __isl_give isl_union_set *isl_union_pw_aff_domain( |
| __isl_take isl_union_pw_aff *upa); |
| __isl_give isl_union_set *isl_union_pw_multi_aff_domain( |
| __isl_take isl_union_pw_multi_aff *upma); |
| __isl_give isl_union_set * |
| isl_multi_union_pw_aff_domain( |
| __isl_take isl_multi_union_pw_aff *mupa); |
| __isl_give isl_set *isl_pw_aff_params( |
| __isl_take isl_pw_aff *pwa); |
| |
| If no explicit domain was set on a zero-dimensional input to |
| C<isl_multi_union_pw_aff_domain>, then this function will |
| return a parameter set. |
| |
| #include <isl/polynomial.h> |
| __isl_give isl_qpolynomial * |
| isl_qpolynomial_project_domain_on_params( |
| __isl_take isl_qpolynomial *qp); |
| __isl_give isl_pw_qpolynomial * |
| isl_pw_qpolynomial_project_domain_on_params( |
| __isl_take isl_pw_qpolynomial *pwqp); |
| __isl_give isl_pw_qpolynomial_fold * |
| isl_pw_qpolynomial_fold_project_domain_on_params( |
| __isl_take isl_pw_qpolynomial_fold *pwf); |
| __isl_give isl_set *isl_pw_qpolynomial_domain( |
| __isl_take isl_pw_qpolynomial *pwqp); |
| __isl_give isl_union_set *isl_union_pw_qpolynomial_fold_domain( |
| __isl_take isl_union_pw_qpolynomial_fold *upwf); |
| __isl_give isl_union_set *isl_union_pw_qpolynomial_domain( |
| __isl_take isl_union_pw_qpolynomial *upwqp); |
| |
| #include <isl/space.h> |
| __isl_give isl_space *isl_space_domain_map( |
| __isl_take isl_space *space); |
| __isl_give isl_space *isl_space_range_map( |
| __isl_take isl_space *space); |
| |
| #include <isl/map.h> |
| __isl_give isl_map *isl_set_wrapped_domain_map( |
| __isl_take isl_set *set); |
| __isl_give isl_basic_map *isl_basic_map_domain_map( |
| __isl_take isl_basic_map *bmap); |
| __isl_give isl_basic_map *isl_basic_map_range_map( |
| __isl_take isl_basic_map *bmap); |
| __isl_give isl_map *isl_map_domain_map(__isl_take isl_map *map); |
| __isl_give isl_map *isl_map_range_map(__isl_take isl_map *map); |
| |
| #include <isl/union_map.h> |
| __isl_give isl_union_map *isl_union_map_domain_map( |
| __isl_take isl_union_map *umap); |
| __isl_give isl_union_pw_multi_aff * |
| isl_union_map_domain_map_union_pw_multi_aff( |
| __isl_take isl_union_map *umap); |
| __isl_give isl_union_map *isl_union_map_range_map( |
| __isl_take isl_union_map *umap); |
| __isl_give isl_union_map * |
| isl_union_set_wrapped_domain_map( |
| __isl_take isl_union_set *uset); |
| |
| The functions above construct a (basic, regular or union) relation |
| that maps (a wrapped version of) the input relation to its domain or range. |
| C<isl_set_wrapped_domain_map> maps the input set to the domain |
| of its wrapped relation. |
| |
| =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); |
| __isl_give isl_basic_map *isl_basic_map_eliminate( |
| __isl_take isl_basic_map *bmap, |
| enum isl_dim_type type, |
| unsigned first, unsigned n); |
| __isl_give isl_map *isl_map_eliminate( |
| __isl_take isl_map *map, enum isl_dim_type type, |
| unsigned first, unsigned n); |
| |
| Eliminate the coefficients for the given dimensions from the constraints, |
| without removing the dimensions. |
| |
| =item * Constructing a set from a parameter domain |
| |
| A zero-dimensional (local) space or (basic) set can be constructed |
| on a given parameter domain using the following functions. |
| |
| #include <isl/space.h> |
| __isl_give isl_space *isl_space_set_from_params( |
| __isl_take isl_space *space); |
| |
| #include <isl/local_space.h> |
| __isl_give isl_local_space * |
| isl_local_space_set_from_params( |
| __isl_take isl_local_space *ls); |
| |
| #include <isl/set.h> |
| __isl_give isl_basic_set *isl_basic_set_from_params( |
| __isl_take isl_basic_set *bset); |
| __isl_give isl_set *isl_set_from_params( |
| __isl_take isl_set *set); |
| |
| =item * Constructing a relation from one or two sets |
| |
| Create a relation with the given set(s) as domain and/or range. |
| If only the domain or the range is specified, then |
| the range or domain of the created relation is a zero-dimensional |
| flat anonymous space. |
| |
| #include <isl/space.h> |
| __isl_give isl_space *isl_space_from_domain( |
| __isl_take isl_space *space); |
| __isl_give isl_space *isl_space_from_range( |
| __isl_take isl_space *space); |
| __isl_give isl_space *isl_space_map_from_set( |
| __isl_take isl_space *space); |
| __isl_give isl_space *isl_space_map_from_domain_and_range( |
| __isl_take isl_space *domain, |
| __isl_take isl_space *range); |
| |
| #include <isl/local_space.h> |
| __isl_give isl_local_space *isl_local_space_from_domain( |
| __isl_take isl_local_space *ls); |
| |
| #include <isl/map.h> |
| __isl_give isl_map *isl_map_from_domain( |
| __isl_take isl_set *set); |
| __isl_give isl_map *isl_map_from_range( |
| __isl_take isl_set *set); |
| |
| #include <isl/union_map.h> |
| __isl_give isl_union_map *isl_union_map_from_domain( |
| __isl_take isl_union_set *uset); |
| __isl_give isl_union_map *isl_union_map_from_range( |
| __isl_take isl_union_set *uset); |
| __isl_give isl_union_map * |
| isl_union_map_from_domain_and_range( |
| __isl_take isl_union_set *domain, |
| __isl_take isl_union_set *range); |
| |
| #include <isl/val.h> |
| __isl_give isl_multi_val *isl_multi_val_from_range( |
| __isl_take isl_multi_val *mv); |
| |
| #include <isl/aff.h> |
| __isl_give isl_aff *isl_aff_from_range( |
| __isl_take isl_aff *aff); |
| __isl_give isl_multi_aff *isl_multi_aff_from_range( |
| __isl_take isl_multi_aff *ma); |
| __isl_give isl_pw_aff *isl_pw_aff_from_range( |
| __isl_take isl_pw_aff *pwa); |
| __isl_give isl_multi_pw_aff *isl_multi_pw_aff_from_range( |
| __isl_take isl_multi_pw_aff *mpa); |
| __isl_give isl_multi_union_pw_aff * |
| isl_multi_union_pw_aff_from_range( |
| __isl_take isl_multi_union_pw_aff *mupa); |
| __isl_give isl_pw_multi_aff *isl_pw_multi_aff_from_domain( |
| __isl_take isl_set *set); |
| __isl_give isl_union_pw_multi_aff * |
| isl_union_pw_multi_aff_from_domain( |
| __isl_take isl_union_set *uset); |
| |
| #include <isl/polynomial.h> |
| __isl_give isl_pw_qpolynomial * |
| isl_pw_qpolynomial_from_range( |
| __isl_take isl_pw_qpolynomial *pwqp); |
| __isl_give isl_pw_qpolynomial_fold * |
| isl_pw_qpolynomial_fold_from_range( |
| __isl_take isl_pw_qpolynomial_fold *pwf); |
| |
| =item * Slicing |
| |
| #include <isl/set.h> |
| __isl_give isl_basic_set *isl_basic_set_fix_si( |
| __isl_take isl_basic_set *bset, |
| enum isl_dim_type type, unsigned pos, int value); |
| __isl_give isl_basic_set *isl_basic_set_fix_val( |
| __isl_take isl_basic_set *bset, |
| enum isl_dim_type type, unsigned pos, |
| __isl_take isl_val *v); |
| __isl_give isl_set *isl_set_fix_si(__isl_take isl_set *set, |
| enum isl_dim_type type, unsigned pos, int value); |
| __isl_give isl_set *isl_set_fix_val( |
| __isl_take isl_set *set, |
| enum isl_dim_type type, unsigned pos, |
| __isl_take isl_val *v); |
| |
| #include <isl/map.h> |
| __isl_give isl_basic_map *isl_basic_map_fix_si( |
| __isl_take isl_basic_map *bmap, |
| enum isl_dim_type type, unsigned pos, int value); |
| __isl_give isl_basic_map *isl_basic_map_fix_val( |
| __isl_take isl_basic_map *bmap, |
| enum isl_dim_type type, unsigned pos, |
| __isl_take isl_val *v); |
| __isl_give isl_map *isl_map_fix_si(__isl_take isl_map *map, |
| enum isl_dim_type type, unsigned pos, int value); |
| __isl_give isl_map *isl_map_fix_val( |
| __isl_take isl_map *map, |
| enum isl_dim_type type, unsigned pos, |
| __isl_take isl_val *v); |
| |
| #include <isl/aff.h> |
| __isl_give isl_pw_multi_aff *isl_pw_multi_aff_fix_si( |
| __isl_take isl_pw_multi_aff *pma, |
| enum isl_dim_type type, unsigned pos, int value); |
| |
| #include <isl/polynomial.h> |
| __isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_fix_val( |
| __isl_take isl_pw_qpolynomial *pwqp, |
| enum isl_dim_type type, unsigned n, |
| __isl_take isl_val *v); |
| __isl_give isl_pw_qpolynomial_fold * |
| isl_pw_qpolynomial_fold_fix_val( |
| __isl_take isl_pw_qpolynomial_fold *pwf, |
| enum isl_dim_type type, unsigned n, |
| __isl_take isl_val *v); |
| |
| Intersect the set, relation or function domain |
| with the hyperplane where the given |
| dimension has the fixed given value. |
| |
| #include <isl/set.h> |
| __isl_give isl_basic_set * |
| isl_basic_set_lower_bound_val( |
| __isl_take isl_basic_set *bset, |
| enum isl_dim_type type, unsigned pos, |
| __isl_take isl_val *value); |
| __isl_give isl_basic_set * |
| isl_basic_set_upper_bound_val( |
| __isl_take isl_basic_set *bset, |
| enum isl_dim_type type, unsigned pos, |
| __isl_take isl_val *value); |
| __isl_give isl_set *isl_set_lower_bound_si( |
| __isl_take isl_set *set, |
| enum isl_dim_type type, unsigned pos, int value); |
| __isl_give isl_set *isl_set_lower_bound_val( |
| __isl_take isl_set *set, |
| enum isl_dim_type type, unsigned pos, |
| __isl_take isl_val *value); |
| __isl_give isl_set *isl_set_upper_bound_si( |
| __isl_take isl_set *set, |
| enum isl_dim_type type, unsigned pos, int value); |
| __isl_give isl_set *isl_set_upper_bound_val( |
| __isl_take isl_set *set, |
| enum isl_dim_type type, unsigned pos, |
| __isl_take isl_val *value); |
| |
| #include <isl/map.h> |
| __isl_give isl_basic_map *isl_basic_map_lower_bound_si( |
| __isl_take isl_basic_map *bmap, |
| enum isl_dim_type type, unsigned pos, int value); |
| __isl_give isl_basic_map *isl_basic_map_upper_bound_si( |
| __isl_take isl_basic_map *bmap, |
| enum isl_dim_type type, unsigned pos, int value); |
| __isl_give isl_map *isl_map_lower_bound_si( |
| __isl_take isl_map *map, |
| enum isl_dim_type type, unsigned pos, int value); |
| __isl_give isl_map *isl_map_upper_bound_si( |
| __isl_take isl_map *map, |
| enum isl_dim_type type, unsigned pos, int value); |
| |
| Intersect the set or relation with the half-space where the given |
| dimension has a value bounded by the fixed given integer value. |
| |
| __isl_give isl_set *isl_set_equate(__isl_take isl_set *set, |
| enum isl_dim_type type1, int pos1, |
| enum isl_dim_type type2, int pos2); |
| __isl_give isl_basic_map *isl_basic_map_equate( |
| __isl_take isl_basic_map *bmap, |
| enum isl_dim_type type1, int pos1, |
| enum isl_dim_type type2, int pos2); |
| __isl_give isl_map *isl_map_equate(__isl_take isl_map *map, |
| enum isl_dim_type type1, int pos1, |
| enum isl_dim_type type2, int pos2); |
| |
| Intersect the set or relation with the hyperplane where the given |
| dimensions are equal to each other. |
| |
| __isl_give isl_map *isl_map_oppose(__isl_take isl_map *map, |
| enum isl_dim_type type1, int pos1, |
| enum isl_dim_type type2, int pos2); |
| |
| Intersect the relation with the hyperplane where the given |
| dimensions have opposite values. |
| |
| __isl_give isl_map *isl_map_order_le( |
| __isl_take isl_map *map, |
| enum isl_dim_type type1, int pos1, |
| enum isl_dim_type type2, int pos2); |
| __isl_give isl_basic_map *isl_basic_map_order_ge( |
| __isl_take isl_basic_map *bmap, |
| enum isl_dim_type type1, int pos1, |
| enum isl_dim_type type2, int pos2); |
| __isl_give isl_map *isl_map_order_ge( |
| __isl_take isl_map *map, |
| enum isl_dim_type type1, int pos1, |
| enum isl_dim_type type2, int pos2); |
| __isl_give isl_map *isl_map_order_lt(__isl_take isl_map *map, |
| enum isl_dim_type type1, int pos1, |
| enum isl_dim_type type2, int pos2); |
| __isl_give isl_basic_map *isl_basic_map_order_gt( |
| __isl_take isl_basic_map *bmap, |
| enum isl_dim_type type1, int pos1, |
| enum isl_dim_type type2, int pos2); |
| __isl_give isl_map *isl_map_order_gt(__isl_take isl_map *map, |
| enum isl_dim_type type1, int pos1, |
| enum isl_dim_type type2, int pos2); |
| |
| Intersect the relation with the half-space where the given |
| dimensions satisfy the given ordering. |
| |
| #include <isl/union_set.h> |
| __isl_give isl_union_map *isl_union_map_remove_map_if( |
| __isl_take isl_union_map *umap, |
| isl_bool (*fn)(__isl_keep isl_map *map, |
| void *user), void *user); |
| |
| This function calls the callback function once for each |
| pair of spaces for which there are elements in the input. |
| If the callback returns C<isl_bool_true>, then all those elements |
| are removed from the result. The only remaining elements in the output |
| are then those for which the callback returns C<isl_bool_false>. |
| |
| =item * Locus |
| |
| #include <isl/aff.h> |
| __isl_give isl_basic_set *isl_aff_zero_basic_set( |
| __isl_take isl_aff *aff); |
| __isl_give isl_basic_set *isl_aff_neg_basic_set( |
| __isl_take isl_aff *aff); |
| __isl_give isl_set *isl_pw_aff_pos_set( |
| __isl_take isl_pw_aff *pa); |
| __isl_give isl_set *isl_pw_aff_nonneg_set( |
| __isl_take isl_pw_aff *pwaff); |
| __isl_give isl_set *isl_pw_aff_zero_set( |
| __isl_take isl_pw_aff *pwaff); |
| __isl_give isl_set *isl_pw_aff_non_zero_set( |
| __isl_take isl_pw_aff *pwaff); |
| __isl_give isl_union_set * |
| isl_union_pw_aff_zero_union_set( |
| __isl_take isl_union_pw_aff *upa); |
| __isl_give isl_union_set * |
| isl_multi_union_pw_aff_zero_union_set( |
| __isl_take isl_multi_union_pw_aff *mupa); |
| |
| 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_pw_aff_nonneg_set> returns a set |
| containing those elements in the domain |
| of C<pwaff> where C<pwaff> is non-negative. |
| The function C<isl_multi_union_pw_aff_zero_union_set> |
| returns a union set containing those elements |
| in the domains of its elements where they are all zero. |
| |
| =item * Identity |
| |
| __isl_give isl_map *isl_set_identity( |
| __isl_take isl_set *set); |
| __isl_give isl_union_map *isl_union_set_identity( |
| __isl_take isl_union_set *uset); |
| __isl_give isl_union_pw_multi_aff * |
| isl_union_set_identity_union_pw_multi_aff( |
| __isl_take isl_union_set *uset); |
| |
| Construct an identity relation on the given (union) set. |
| |
| =item * Function Extraction |
| |
| A piecewise quasi affine expression that is equal to 1 on a set |
| and 0 outside the set can be created using the following function. |
| |
| #include <isl/aff.h> |
| __isl_give isl_pw_aff *isl_set_indicator_function( |
| __isl_take isl_set *set); |
| |
| A piecewise multiple quasi affine expression can be extracted |
| from an C<isl_set> or C<isl_map>, provided the C<isl_set> is a singleton |
| and the C<isl_map> is single-valued. |
| In case of a conversion from an C<isl_union_map> |
| to an C<isl_union_pw_multi_aff>, these properties need to hold |
| in each domain space. |
| A conversion to a C<isl_multi_union_pw_aff> additionally |
| requires that the input is non-empty and involves only a single |
| range space. |
| |
| #include <isl/aff.h> |
| __isl_give isl_pw_multi_aff *isl_pw_multi_aff_from_set( |
| __isl_take isl_set *set); |
| __isl_give isl_pw_multi_aff *isl_pw_multi_aff_from_map( |
| __isl_take isl_map *map); |
| |
| __isl_give isl_union_pw_multi_aff * |
| isl_union_pw_multi_aff_from_union_set( |
| __isl_take isl_union_set *uset); |
| __isl_give isl_union_pw_multi_aff * |
| isl_union_pw_multi_aff_from_union_map( |
| __isl_take isl_union_map *umap); |
| |
| __isl_give isl_multi_union_pw_aff * |
| isl_multi_union_pw_aff_from_union_map( |
| __isl_take isl_union_map *umap); |
| |
| =item * Deltas |
| |
| __isl_give isl_basic_set *isl_basic_map_deltas( |
| __isl_take isl_basic_map *bmap); |
| __isl_give isl_set *isl_map_deltas(__isl_take isl_map *map); |
| __isl_give isl_union_set *isl_union_map_deltas( |
| __isl_take isl_union_map *umap); |
| |
| These functions return a (basic) set containing the differences |
| between image elements and corresponding domain elements in the input. |
| |
| __isl_give isl_basic_map *isl_basic_map_deltas_map( |
| __isl_take isl_basic_map *bmap); |
| __isl_give isl_map *isl_map_deltas_map( |
| __isl_take isl_map *map); |
| __isl_give isl_union_map *isl_union_map_deltas_map( |
| __isl_take isl_union_map *umap); |
| |
| The functions above construct a (basic, regular or union) relation |
| that maps (a wrapped version of) the input relation to its delta set. |
| |
| =item * Coalescing |
| |
| Simplify the representation of a set, relation or functions by trying |
| to combine pairs of basic sets or relations into a single |
| basic set or relation. |
| |
| #include <isl/set.h> |
| __isl_give isl_set *isl_set_coalesce(__isl_take isl_set *set); |
| |
| #include <isl/map.h> |
| __isl_give isl_map *isl_map_coalesce(__isl_take isl_map *map); |
| |
| #include <isl/union_set.h> |
| __isl_give isl_union_set *isl_union_set_coalesce( |
| __isl_take isl_union_set *uset); |
| |
| #include <isl/union_map.h> |
| __isl_give isl_union_map *isl_union_map_coalesce( |
| __isl_take isl_union_map *umap); |
| |
| #include <isl/aff.h> |
| __isl_give isl_pw_aff *isl_pw_aff_coalesce( |
| __isl_take isl_pw_aff *pwqp); |
| __isl_give isl_pw_multi_aff *isl_pw_multi_aff_coalesce( |
| __isl_take isl_pw_multi_aff *pma); |
| __isl_give isl_multi_pw_aff *isl_multi_pw_aff_coalesce( |
| __isl_take isl_multi_pw_aff *mpa); |
| __isl_give isl_union_pw_aff *isl_union_pw_aff_coalesce( |
| __isl_take isl_union_pw_aff *upa); |
| __isl_give isl_union_pw_multi_aff * |
| isl_union_pw_multi_aff_coalesce( |
| __isl_take isl_union_pw_multi_aff *upma); |
| __isl_give isl_multi_union_pw_aff * |
| isl_multi_union_pw_aff_coalesce( |
| __isl_take isl_multi_union_pw_aff *aff); |
| |
| #include <isl/polynomial.h> |
| __isl_give isl_pw_qpolynomial_fold * |
| isl_pw_qpolynomial_fold_coalesce( |
| __isl_take isl_pw_qpolynomial_fold *pwf); |
| __isl_give isl_union_pw_qpolynomial * |
| isl_union_pw_qpolynomial_coalesce( |
| __isl_take isl_union_pw_qpolynomial *upwqp); |
| __isl_give isl_union_pw_qpolynomial_fold * |
| isl_union_pw_qpolynomial_fold_coalesce( |
| __isl_take isl_union_pw_qpolynomial_fold *upwf); |
| |
| One of the methods for combining pairs of basic sets or relations |
| can result in coefficients that are much larger than those that appear |
| in the constraints of the input. By default, the coefficients are |
| not allowed to grow larger, but this can be changed by unsetting |
| the following option. |
| |
| isl_stat isl_options_set_coalesce_bounded_wrapping( |
| isl_ctx *ctx, int val); |
| int isl_options_get_coalesce_bounded_wrapping( |
| isl_ctx *ctx); |
| |
| =item * Detecting equalities |
| |
| __isl_give isl_basic_set *isl_basic_set_detect_equalities( |
| __isl_take isl_basic_set *bset); |
| __isl_give isl_basic_map *isl_basic_map_detect_equalities( |
| __isl_take isl_basic_map *bmap); |
| __isl_give isl_set *isl_set_detect_equalities( |
| __isl_take isl_set *set); |
| __isl_give isl_map *isl_map_detect_equalities( |
| __isl_take isl_map *map); |
| __isl_give isl_union_set *isl_union_set_detect_equalities( |
| __isl_take isl_union_set *uset); |
| __isl_give isl_union_map *isl_union_map_detect_equalities( |
| __isl_take isl_union_map *umap); |
| |
| Simplify the representation of a set or relation by detecting implicit |
| equalities. |
| |
| =item * Removing redundant constraints |
| |
| #include <isl/set.h> |
| __isl_give isl_basic_set *isl_basic_set_remove_redundancies( |
| __isl_take isl_basic_set *bset); |
| __isl_give isl_set *isl_set_remove_redundancies( |
| __isl_take isl_set *set); |
| |
| #include <isl/union_set.h> |
| __isl_give isl_union_set * |
| isl_union_set_remove_redundancies( |
| __isl_take isl_union_set *uset); |
| |
| #include <isl/map.h> |
| __isl_give isl_basic_map *isl_basic_map_remove_redundancies( |
| __isl_take isl_basic_map *bmap); |
| __isl_give isl_map *isl_map_remove_redundancies( |
| __isl_take isl_map *map); |
| |
| #include <isl/union_map.h> |
| __isl_give isl_union_map * |
| isl_union_map_remove_redundancies( |
| __isl_take isl_union_map *umap); |
| |
| =item * Convex hull |
| |
| __isl_give isl_basic_set *isl_set_convex_hull( |
| __isl_take isl_set *set); |
| __isl_give isl_basic_map *isl_map_convex_hull( |
| __isl_take isl_map *map); |
| |
| If the input set or relation has any existentially quantified |
| variables, then the result of these operations is currently undefined. |
| |
| =item * Simple hull |
| |
| #include <isl/set.h> |
| __isl_give isl_basic_set * |
| isl_set_unshifted_simple_hull( |
| __isl_take isl_set *set); |
| __isl_give isl_basic_set *isl_set_simple_hull( |
| __isl_take isl_set *set); |
| __isl_give isl_basic_set * |
| isl_set_plain_unshifted_simple_hull( |
| __isl_take isl_set *set); |
| __isl_give isl_basic_set * |
| isl_set_unshifted_simple_hull_from_set_list( |
| __isl_take isl_set *set, |
| __isl_take isl_set_list *list); |
| |
| #include <isl/map.h> |
| __isl_give isl_basic_map * |
| isl_map_unshifted_simple_hull( |
| __isl_take isl_map *map); |
| __isl_give isl_basic_map *isl_map_simple_hull( |
| __isl_take isl_map *map); |
| __isl_give isl_basic_map * |
| isl_map_plain_unshifted_simple_hull( |
| __isl_take isl_map *map); |
| __isl_give isl_basic_map * |
| isl_map_unshifted_simple_hull_from_map_list( |
| __isl_take isl_map *map, |
| __isl_take isl_map_list *list); |
| |
| #include <isl/union_map.h> |
| __isl_give isl_union_map *isl_union_map_simple_hull( |
| __isl_take isl_union_map *umap); |
| |
| These functions compute a single basic set or relation |
| that contains the whole input set or relation. |
| In particular, the output is described by translates |
| of the constraints describing the basic sets or relations in the input. |
| In case of C<isl_set_unshifted_simple_hull>, only the original |
| constraints are used, without any translation. |
| In case of C<isl_set_plain_unshifted_simple_hull> and |
| C<isl_map_plain_unshifted_simple_hull>, the result is described |
| by original constraints that are obviously satisfied |
| by the entire input set or relation. |
| In case of C<isl_set_unshifted_simple_hull_from_set_list> and |
| C<isl_map_unshifted_simple_hull_from_map_list>, the |
| constraints are taken from the elements of the second argument. |
| |
| =begin latex |
| |
| (See \autoref{s:simple hull}.) |
| |
| =end latex |
| |
| =item * Affine hull |
| |
| __isl_give isl_basic_set *isl_basic_set_affine_hull( |
| __isl_take isl_basic_set *bset); |
| __isl_give isl_basic_set *isl_set_affine_hull( |
| __isl_take isl_set *set); |
| __isl_give isl_union_set *isl_union_set_affine_hull( |
| __isl_take isl_union_set *uset); |
| __isl_give isl_basic_map *isl_basic_map_affine_hull( |
| __isl_take isl_basic_map *bmap); |
| __isl_give isl_basic_map *isl_map_affine_hull( |
| __isl_take isl_map *map); |
| __isl_give isl_union_map *isl_union_map_affine_hull( |
| __isl_take isl_union_map *umap); |
| |
| In case of union sets and relations, the affine hull is computed |
| per space. |
| |
| =item * Polyhedral hull |
| |
| __isl_give isl_basic_set *isl_set_polyhedral_hull( |
| __isl_take isl_set *set); |
| __isl_give isl_basic_map *isl_map_polyhedral_hull( |
| __isl_take isl_map *map); |
| __isl_give isl_union_set *isl_union_set_polyhedral_hull( |
| __isl_take isl_union_set *uset); |
| __isl_give isl_union_map *isl_union_map_polyhedral_hull( |
| __isl_take isl_union_map *umap); |
| |
| These functions compute a single basic set or relation |
| not involving any existentially quantified variables |
| that contains the whole input set or relation. |
| In case of union sets and relations, the polyhedral hull is computed |
| per space. |
| |
| =item * Box hull |
| |
| #include <isl/map.h> |
| __isl_give isl_fixed_box * |
| isl_map_get_range_simple_fixed_box_hull( |
| __isl_keep isl_map *map); |
| |
| This function tries to approximate the range of the map by a box of fixed size. |
| The box is described in terms of an offset living in the same space as |
| the input map and a size living in the range space. For any element |
| in the input map, the range value is greater than or equal to |
| the offset applied to the domain value and the difference with |
| this offset is strictly smaller than the size. |
| If no fixed-size approximation of the range can be found, |
| an I<invalid> box is returned, i.e., one for which |
| C<isl_fixed_box_is_valid> below returns false. |
| |
| The validity, the offset and the size of the box can be obtained using |
| the following functions. |
| |
| #include <isl/fixed_box.h> |
| isl_bool isl_fixed_box_is_valid( |
| __isl_keep isl_fixed_box *box); |
| __isl_give isl_multi_aff *isl_fixed_box_get_offset( |
| __isl_keep isl_fixed_box *box); |
| __isl_give isl_multi_val *isl_fixed_box_get_size( |
| __isl_keep isl_fixed_box *box); |
| |
| The box can be copied and freed using the following functions. |
| |
| #include <isl/fixed_box.h> |
| __isl_give isl_fixed_box *isl_fixed_box_copy( |
| __isl_keep isl_fixed_box *box); |
| __isl_null isl_fixed_box *isl_fixed_box_free( |
| __isl_take isl_fixed_box *box); |
| |
| =item * Other approximations |
| |
| #include <isl/set.h> |
| __isl_give isl_basic_set * |
| isl_basic_set_drop_constraints_involving_dims( |
| __isl_take isl_basic_set *bset, |
| enum isl_dim_type type, |
| unsigned first, unsigned n); |
| __isl_give isl_basic_set * |
| isl_basic_set_drop_constraints_not_involving_dims( |
| __isl_take isl_basic_set *bset, |
| enum isl_dim_type type, |
| unsigned first, unsigned n); |
| __isl_give isl_set * |
| isl_set_drop_constraints_involving_dims( |
| __isl_take isl_set *set, |
| enum isl_dim_type type, |
| unsigned first, unsigned n); |
| __isl_give isl_set * |
| isl_set_drop_constraints_not_involving_dims( |
| __isl_take isl_set *set, |
| enum isl_dim_type type, |
| unsigned first, unsigned n); |
| |
| #include <isl/map.h> |
| __isl_give isl_basic_map * |
| isl_basic_map_drop_constraints_involving_dims( |
| __isl_take isl_basic_map *bmap, |
| enum isl_dim_type type, |
| unsigned first, unsigned n); |
| __isl_give isl_basic_map * |
| isl_basic_map_drop_constraints_not_involving_dims( |
| __isl_take isl_basic_map *bmap, |
| enum isl_dim_type type, |
| unsigned first, unsigned n); |
| __isl_give isl_map * |
| isl_map_drop_constraints_involving_dims( |
| __isl_take isl_map *map, |
| enum isl_dim_type type, |
| unsigned first, unsigned n); |
| __isl_give isl_map * |
| isl_map_drop_constraints_not_involving_dims( |
| __isl_take isl_map *map, |
| enum isl_dim_type type, |
| unsigned first, unsigned n); |
| |
| These functions drop any constraints (not) involving the specified dimensions. |
| Note that the result depends on the representation of the input. |
| |
| #include <isl/polynomial.h> |
| __isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_to_polynomial( |
| __isl_take isl_pw_qpolynomial *pwqp, int sign); |
| __isl_give isl_union_pw_qpolynomial * |
| isl_union_pw_qpolynomial_to_polynomial( |
| __isl_take isl_union_pw_qpolynomial *upwqp, int sign); |
| |
| Approximate each quasipolynomial by a polynomial. If C<sign> is positive, |
| the polynomial will be an overapproximation. If C<sign> is negative, |
| it will be an underapproximation. If C<sign> is zero, the approximation |
| will lie somewhere in between. |
| |
| =item * Feasibility |
| |
| __isl_give isl_basic_set *isl_basic_set_sample( |
| __isl_take isl_basic_set *bset); |
| __isl_give isl_basic_set *isl_set_sample( |
| __isl_take isl_set *set); |
| __isl_give isl_basic_map *isl_basic_map_sample( |
| __isl_take isl_basic_map *bmap); |
| __isl_give isl_basic_map *isl_map_sample( |
| __isl_take isl_map *map); |
| |
| If the input (basic) set or relation is non-empty, then return |
| a singleton subset of the input. Otherwise, return an empty set. |
| |
| =item * Optimization |
| |
| #include <isl/ilp.h> |
| __isl_give isl_val *isl_basic_set_max_val( |
| __isl_keep isl_basic_set *bset, |
| __isl_keep isl_aff *obj); |
| __isl_give isl_val *isl_set_min_val( |
| __isl_keep isl_set *set, |
| __isl_keep isl_aff *obj); |
| __isl_give isl_val *isl_set_max_val( |
| __isl_keep isl_set *set, |
| __isl_keep isl_aff *obj); |
| __isl_give isl_multi_val * |
| isl_union_set_min_multi_union_pw_aff( |
| __isl_keep isl_union_set *uset, |
| __isl_keep isl_multi_union_pw_aff *obj); |
| |
| Compute the minimum or maximum of the integer affine expression C<obj> |
| over the points in C<set>. |
| The result is C<NULL> in case of an error, the optimal value in case |
| there is one, negative infinity or infinity if the problem is unbounded and |
| NaN if the problem is empty. |
| |
| #include <isl/ilp.h> |
| __isl_give isl_val *isl_union_pw_aff_min_val( |
| __isl_take isl_union_pw_aff *upa); |
| __isl_give isl_val *isl_union_pw_aff_max_val( |
| __isl_take isl_union_pw_aff *upa); |
| __isl_give isl_multi_val * |
| isl_multi_union_pw_aff_min_multi_val( |
| __isl_take isl_multi_union_pw_aff *mupa); |
| __isl_give isl_multi_val * |
| isl_multi_union_pw_aff_max_multi_val( |
| __isl_take isl_multi_union_pw_aff *mupa); |
| |
| Compute the minimum or maximum of the integer affine expression |
| over its definition domain. |
| The result is C<NULL> in case of an error, the optimal value in case |
| there is one, negative infinity or infinity if the problem is unbounded and |
| NaN if the problem is empty. |
| |
| #include <isl/ilp.h> |
| __isl_give isl_val *isl_basic_set_dim_max_val( |
| __isl_take isl_basic_set *bset, int pos); |
| |
| Return the maximal value attained by the given set dimension, |
| independently of the parameter values and of any other dimensions. |
| The result is C<NULL> in case of an error, the optimal value in case |
| there is one, infinity if the problem is unbounded and |
| NaN if the input is empty. |
| |
| =item * Parametric optimization |
| |
| __isl_give isl_pw_aff *isl_set_dim_min( |
| __isl_take isl_set *set, int pos); |
| __isl_give isl_pw_aff *isl_set_dim_max( |
| __isl_take isl_set *set, int pos); |
| __isl_give isl_pw_aff *isl_map_dim_min( |
| __isl_take isl_map *map, int pos); |
| __isl_give isl_pw_aff *isl_map_dim_max( |
| __isl_take isl_map *map, int pos); |
| |
| Compute the minimum or maximum of the given set or output dimension |
| as a function of the parameters (and input dimensions), but independently |
| of the other set or output dimensions. |
| For lexicographic optimization, see L<"Lexicographic Optimization">. |
| |
| =item * Dual |
| |
| The following functions compute either the set of (rational) coefficient |
| values of valid constraints for the given set or the set of (rational) |
| values satisfying the constraints with coefficients from the given set. |
| Internally, these two sets of functions perform essentially the |
| same operations, except that the set of coefficients is assumed to |
| be a cone, while the set of values may be any polyhedron. |
| The current implementation is based on the Farkas lemma and |
| Fourier-Motzkin elimination, but this may change or be made optional |
| in future. In particular, future implementations may use different |
| dualization algorithms or skip the elimination step. |
| |
| #include <isl/set.h> |
| __isl_give isl_basic_set *isl_basic_set_coefficients( |
| __isl_take isl_basic_set *bset); |
| __isl_give isl_basic_set_list * |
| isl_basic_set_list_coefficients( |
| __isl_take isl_basic_set_list *list); |
| __isl_give isl_basic_set *isl_set_coefficients( |
| __isl_take isl_set *set); |
| __isl_give isl_union_set *isl_union_set_coefficients( |
| __isl_take isl_union_set *bset); |
| __isl_give isl_basic_set *isl_basic_set_solutions( |
| __isl_take isl_basic_set *bset); |
| __isl_give isl_basic_set *isl_set_solutions( |
| __isl_take isl_set *set); |
| __isl_give isl_union_set *isl_union_set_solutions( |
| __isl_take isl_union_set *bset); |
| |
| =item * Power |
| |
| __isl_give isl_map *isl_map_fixed_power_val( |
| __isl_take isl_map *map, |
| __isl_take isl_val *exp); |
| __isl_give isl_union_map * |
| isl_union_map_fixed_power_val( |
| __isl_take isl_union_map *umap, |
| __isl_take isl_val *exp); |
| |
| Compute the given power of C<map>, where C<exp> is assumed to be non-zero. |
| If the exponent C<exp> is negative, then the -C<exp> th power of the inverse |
| of C<map> is computed. |
| |
| __isl_give isl_map *isl_map_power(__isl_take isl_map *map, |
| int *exact); |
| __isl_give isl_union_map *isl_union_map_power( |
| __isl_take isl_union_map *umap, int *exact); |
| |
| Compute a parametric representation for all positive powers I<k> of C<map>. |
| The result maps I<k> to a nested relation corresponding to the |
| I<k>th power of C<map>. |
| The result may be an overapproximation. If the result is known to be exact, |
| then C<*exact> is set to C<1>. |
| |
| =item * Transitive closure |
| |
| __isl_give isl_map *isl_map_transitive_closure( |
| __isl_take isl_map *map, int *exact); |
| __isl_give isl_union_map *isl_union_map_transitive_closure( |
| __isl_take isl_union_map *umap, int *exact); |
| |
| Compute the transitive closure of C<map>. |
| The result may be an overapproximation. If the result is known to be exact, |
| then C<*exact> is set to C<1>. |
| |
| =item * Reaching path lengths |
| |
| __isl_give isl_map *isl_map_reaching_path_lengths( |
| __isl_take isl_map *map, int *exact); |
| |
| Compute a relation that maps each element in the range of C<map> |
| to the lengths of all paths composed of edges in C<map> that |
| end up in the given element. |
| The result may be an overapproximation. If the result is known to be exact, |
| then C<*exact> is set to C<1>. |
| To compute the I<maximal> path length, the resulting relation |
| should be postprocessed by C<isl_map_lexmax>. |
| In particular, if the input relation is a dependence relation |
| (mapping sources to sinks), then the maximal path length corresponds |
| to the free schedule. |
| Note, however, that C<isl_map_lexmax> expects the maximum to be |
| finite, so if the path lengths are unbounded (possibly due to |
| the overapproximation), then you will get an error message. |
| |
| =item * Wrapping |
| |
| #include <isl/space.h> |
| __isl_give isl_space *isl_space_wrap( |
| __isl_take isl_space *space); |
| __isl_give isl_space *isl_space_unwrap( |
| __isl_take isl_space *space); |
| |
| #include <isl/local_space.h> |
| __isl_give isl_local_space *isl_local_space_wrap( |
| __isl_take isl_local_space *ls); |
| |
| #include <isl/set.h> |
| __isl_give isl_basic_map *isl_basic_set_unwrap( |
| __isl_take isl_basic_set *bset); |
| __isl_give isl_map *isl_set_unwrap( |
| __isl_take isl_set *set); |
| |
| #include <isl/map.h> |
| __isl_give isl_basic_set *isl_basic_map_wrap( |
| __isl_take isl_basic_map *bmap); |
| __isl_give isl_set *isl_map_wrap( |
| __isl_take isl_map *map); |
| |
| #include <isl/union_set.h> |
| __isl_give isl_union_map *isl_union_set_unwrap( |
| __isl_take isl_union_set *uset); |
| |
| #include <isl/union_map.h> |
| __isl_give isl_union_set *isl_union_map_wrap( |
| __isl_take isl_union_map *umap); |
| |
| The input to C<isl_space_unwrap> should |
| be the space of a set, while that of |
| C<isl_space_wrap> should be the space of a relation. |
| Conversely, the output of C<isl_space_unwrap> is the space |
| of a relation, while that of C<isl_space_wrap> is the space of a set. |
| |
| =item * Flattening |
| |
| Remove any internal structure of domain (and range) of the given |
| set or relation. If there is any such internal structure in the input, |
| then the name of the space is also removed. |
| |
| #include <isl/space.h> |
| __isl_give isl_space *isl_space_flatten_domain( |
| __isl_take isl_space *space); |
| __isl_give isl_space *isl_space_flatten_range( |
| __isl_take isl_space *space); |
| |
| #include <isl/local_space.h> |
| __isl_give isl_local_space * |
| isl_local_space_flatten_domain( |
| __isl_take isl_local_space *ls); |
| __isl_give isl_local_space * |
| isl_local_space_flatten_range( |
| __isl_take isl_local_space *ls); |
| |
| #include <isl/set.h> |
| __isl_give isl_basic_set *isl_basic_set_flatten( |
| __isl_take isl_basic_set *bset); |
| __isl_give isl_set *isl_set_flatten( |
| __isl_take isl_set *set); |
| |
| #include <isl/map.h> |
| __isl_give isl_basic_map *isl_basic_map_flatten_domain( |
| __isl_take isl_basic_map *bmap); |
| __isl_give isl_basic_map *isl_basic_map_flatten_range( |
| __isl_take isl_basic_map *bmap); |
| __isl_give isl_map *isl_map_flatten_range( |
| __isl_take isl_map *map); |
| __isl_give isl_map *isl_map_flatten_domain( |
| __isl_take isl_map *map); |
| __isl_give isl_basic_map *isl_basic_map_flatten( |
| __isl_take isl_basic_map *bmap); |
| __isl_give isl_map *isl_map_flatten( |
| __isl_take isl_map *map); |
| |
| #include <isl/val.h> |
| __isl_give isl_multi_val *isl_multi_val_flatten_range( |
| __isl_take isl_multi_val *mv); |
| |
| #include <isl/aff.h> |
| __isl_give isl_multi_aff *isl_multi_aff_flatten_domain( |
| __isl_take isl_multi_aff *ma); |
| __isl_give isl_multi_aff *isl_multi_aff_flatten_range( |
| __isl_take isl_multi_aff *ma); |
| __isl_give isl_multi_pw_aff * |
| isl_multi_pw_aff_flatten_range( |
| __isl_take isl_multi_pw_aff *mpa); |
| __isl_give isl_multi_union_pw_aff * |
| isl_multi_union_pw_aff_flatten_range( |
| __isl_take isl_multi_union_pw_aff *mupa); |
| |
| #include <isl/map.h> |
| __isl_give isl_map *isl_set_flatten_map( |
| __isl_take isl_set *set); |
| |
| The function above constructs a relation |
| that maps the input set to a flattened version of the set. |
| |
| =item * Lifting |
| |
| Lift the input set to a space with extra dimensions corresponding |
| to the existentially quantified variables in the input. |
| In particular, the result lives in a wrapped map where the domain |
| is the original space and the range corresponds to the original |
| existentially quantified variables. |
| |
| #include <isl/set.h> |
| __isl_give isl_basic_set *isl_basic_set_lift( |
| __isl_take isl_basic_set *bset); |
| __isl_give isl_set *isl_set_lift( |
| __isl_take isl_set *set); |
| __isl_give isl_union_set *isl_union_set_lift( |
| __isl_take isl_union_set *uset); |
| |
| Given a local space that contains the existentially quantified |
| variables of a set, a basic relation that, when applied to |
| a basic set, has essentially the same effect as C<isl_basic_set_lift>, |
| can be constructed using the following function. |
| |
| #include <isl/local_space.h> |
| __isl_give isl_basic_map *isl_local_space_lifting( |
| __isl_take isl_local_space *ls); |
| |
| #include <isl/aff.h> |
| __isl_give isl_multi_aff *isl_multi_aff_lift( |
| __isl_take isl_multi_aff *maff, |
| __isl_give isl_local_space **ls); |
| |
| If the C<ls> argument of C<isl_multi_aff_lift> is not C<NULL>, |
| then it is assigned the local space that lies at the basis of |
| the lifting applied. |
| |
| =item * Internal Product |
| |
| #include <isl/space.h> |
| __isl_give isl_space *isl_space_zip( |
| __isl_take isl_space *space); |
| |
| #include <isl/map.h> |
| __isl_give isl_basic_map *isl_basic_map_zip( |
| __isl_take isl_basic_map *bmap); |
| __isl_give isl_map *isl_map_zip( |
| __isl_take isl_map *map); |
| |
| #include <isl/union_map.h> |
| __isl_give isl_union_map *isl_union_map_zip( |
| __isl_take isl_union_map *umap); |
| |
| Given a relation with nested relations for domain and range, |
| interchange the range of the domain with the domain of the range. |
| |
| =item * Currying |
| |
| #include <isl/space.h> |
| __isl_give isl_space *isl_space_curry( |
| __isl_take isl_space *space); |
| __isl_give isl_space *isl_space_uncurry( |
| __isl_take isl_space *space); |
| |
| #include <isl/map.h> |
| __isl_give isl_basic_map *isl_basic_map_curry( |
| __isl_take isl_basic_map *bmap); |
| __isl_give isl_basic_map *isl_basic_map_uncurry( |
| __isl_take isl_basic_map *bmap); |
| __isl_give isl_map *isl_map_curry( |
| __isl_take isl_map *map); |
| __isl_give isl_map *isl_map_uncurry( |
| __isl_take isl_map *map); |
| |
| #include <isl/union_map.h> |
| __isl_give isl_union_map *isl_union_map_curry( |
| __isl_take isl_union_map *umap); |
| __isl_give isl_union_map *isl_union_map_uncurry( |
| __isl_take isl_union_map *umap); |
| |
| Given a relation with a nested relation for domain, |
| the C<curry> functions |
| move the range of the nested relation out of the domain |
| and use it as the domain of a nested relation in the range, |
| with the original range as range of this nested relation. |
| The C<uncurry> functions perform the inverse operation. |
| |
| #include <isl/space.h> |
| __isl_give isl_space *isl_space_range_curry( |
| __isl_take isl_space *space); |
| |
| #include <isl/map.h> |
| __isl_give isl_map *isl_map_range_curry( |
| __isl_take isl_map *map); |
| |
| #include <isl/union_map.h> |
| __isl_give isl_union_map *isl_union_map_range_curry( |
| __isl_take isl_union_map *umap); |
| |
| These functions apply the currying to the relation that |
| is nested inside the range of the input. |
| |
| =item * Aligning parameters |
| |
| Change the order of the parameters of the given set, relation |
| or function |
| such that the first parameters match those of C<model>. |
| This may involve the introduction of extra parameters. |
| All parameters need to be named. |
| |
| #include <isl/space.h> |
| __isl_give isl_space *isl_space_align_params( |
| __isl_take isl_space *space1, |
| __isl_take isl_space *space2) |
| |
| #include <isl/set.h> |
| __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); |
| |
| #include <isl/map.h> |
| __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); |
| |
| #include <isl/val.h> |
| __isl_give isl_multi_val *isl_multi_val_align_params( |
| __isl_take isl_multi_val *mv, |
| __isl_take isl_space *model); |
| |
| #include <isl/aff.h> |
| __isl_give isl_aff *isl_aff_align_params( |
| __isl_take isl_aff *aff, |
| __isl_take isl_space *model); |
| __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_aff *isl_pw_aff_align_params( |
| __isl_take isl_pw_aff *pwaff, |
| __isl_take isl_space *model); |
| __isl_give isl_pw_multi_aff *isl_pw_multi_aff_align_params( |
| __isl_take isl_pw_multi_aff *pma, |
| __isl_take isl_space *model); |
| __isl_give isl_union_pw_aff * |
| isl_union_pw_aff_align_params( |
| __isl_take isl_union_pw_aff *upa, |
| __isl_take isl_space *model); |
| __isl_give isl_union_pw_multi_aff * |
| isl_union_pw_multi_aff_align_params( |
| __isl_take isl_union_pw_multi_aff *upma, |
| __isl_take isl_space *model); |
| __isl_give isl_multi_union_pw_aff * |
| isl_multi_union_pw_aff_align_params( |
| __isl_take isl_multi_union_pw_aff *mupa, |
| __isl_take isl_space *model); |
| |
| #include <isl/polynomial.h> |
| __isl_give isl_qpolynomial *isl_qpolynomial_align_params( |
| __isl_take isl_qpolynomial *qp, |
| __isl_take isl_space *model); |
| |
| =item * Drop unused parameters |
| |
| Drop parameters that are not referenced by the isl object. |
| All parameters need to be named. |
| |
| #include <isl/set.h> |
| __isl_give isl_basic_set * |
| isl_basic_set_drop_unused_params( |
| __isl_take isl_basic_set *bset); |
| __isl_give isl_set *isl_set_drop_unused_params( |
| __isl_take isl_set *set); |
| |
| #include <isl/map.h> |
| __isl_give isl_basic_map * |
| isl_basic_map_drop_unused_params( |
| __isl_take isl_basic_map *bmap); |
| __isl_give isl_map *isl_map_drop_unused_params( |
| __isl_take isl_map *map); |
| |
| #include <isl/aff.h> |
| __isl_give isl_pw_aff *isl_pw_aff_drop_unused_params( |
| __isl_take isl_pw_aff *pa); |
| __isl_give isl_pw_multi_aff * |
| isl_pw_multi_aff_drop_unused_params( |
| __isl_take isl_pw_multi_aff *pma); |
| |
| #include <isl/polynomial.h> |
| __isl_give isl_pw_qpolynomial * |
| isl_pw_qpolynomial_drop_unused_params( |
| __isl_take isl_pw_qpolynomial *pwqp); |
| __isl_give isl_pw_qpolynomial_fold * |
| isl_pw_qpolynomial_fold_drop_unused_params( |
| __isl_take isl_pw_qpolynomial_fold *pwf); |
| |
| =item * Unary Arithmetic Operations |
| |
| #include <isl/set.h> |
| __isl_give isl_set *isl_set_neg( |
| __isl_take isl_set *set); |
| #include <isl/map.h> |
| __isl_give isl_map *isl_map_neg( |
| __isl_take isl_map *map); |
| |
| C<isl_set_neg> constructs a set containing the opposites of |
| the elements in its argument. |
| The domain of the result of C<isl_map_neg> is the same |
| as the domain of its argument. The corresponding range |
| elements are the opposites of the corresponding range |
| elements in the argument. |
| |
| #include <isl/val.h> |
| __isl_give isl_multi_val *isl_multi_val_neg( |
| __isl_take isl_multi_val *mv); |
| |
| #include <isl/aff.h> |
| __isl_give isl_aff *isl_aff_neg( |
| __isl_take isl_aff *aff); |
| __isl_give isl_multi_aff *isl_multi_aff_neg( |
| __isl_take isl_multi_aff *ma); |
| __isl_give isl_pw_aff *isl_pw_aff_neg( |
| __isl_take isl_pw_aff *pwaff); |
| __isl_give isl_pw_multi_aff *isl_pw_multi_aff_neg( |
| __isl_take isl_pw_multi_aff *pma); |
| __isl_give isl_multi_pw_aff *isl_multi_pw_aff_neg( |
| __isl_take isl_multi_pw_aff *mpa); |
| __isl_give isl_union_pw_aff *isl_union_pw_aff_neg( |
| __isl_take isl_union_pw_aff *upa); |
| __isl_give isl_union_pw_multi_aff * |
| isl_union_pw_multi_aff_neg( |
| __isl_take isl_union_pw_multi_aff *upma); |
| __isl_give isl_multi_union_pw_aff * |
| isl_multi_union_pw_aff_neg( |
| __isl_take isl_multi_union_pw_aff *mupa); |
| __isl_give isl_aff *isl_aff_ceil( |
| __isl_take isl_aff *aff); |
| __isl_give isl_pw_aff *isl_pw_aff_ceil( |
| __isl_take isl_pw_aff *pwaff); |
| __isl_give isl_aff *isl_aff_floor( |
| __isl_take isl_aff *aff); |
| __isl_give isl_multi_aff *isl_multi_aff_floor( |
| __isl_take isl_multi_aff *ma); |
| __isl_give isl_pw_aff *isl_pw_aff_floor( |
| __isl_take isl_pw_aff *pwaff); |
| __isl_give isl_union_pw_aff *isl_union_pw_aff_floor( |
| __isl_take isl_union_pw_aff *upa); |
| __isl_give isl_multi_union_pw_aff * |
| isl_multi_union_pw_aff_floor( |
| __isl_take isl_multi_union_pw_aff *mupa); |
| |
| #include <isl/aff.h> |
| __isl_give isl_pw_aff *isl_pw_aff_list_min( |
| __isl_take isl_pw_aff_list *list); |
| __isl_give isl_pw_aff *isl_pw_aff_list_max( |
| __isl_take isl_pw_aff_list *list); |
| |
| #include <isl/polynomial.h> |
| __isl_give isl_qpolynomial *isl_qpolynomial_neg( |
| __isl_take isl_qpolynomial *qp); |
| __isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_neg( |
| __isl_take isl_pw_qpolynomial *pwqp); |
| __isl_give isl_union_pw_qpolynomial * |
| isl_union_pw_qpolynomial_neg( |
| __isl_take isl_union_pw_qpolynomial *upwqp); |
| __isl_give isl_qpolynomial *isl_qpolynomial_pow( |
| __isl_take isl_qpolynomial *qp, |
| unsigned exponent); |
| __isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_pow( |
| __isl_take isl_pw_qpolynomial *pwqp, |
| unsigned exponent); |
| |
| =item * Evaluation |
| |
| The following functions evaluate a function in a point. |
| |
| #include <isl/aff.h> |
| __isl_give isl_val *isl_aff_eval( |
| __isl_take isl_aff *aff, |
| __isl_take isl_point *pnt); |
| __isl_give isl_val *isl_pw_aff_eval( |
| __isl_take isl_pw_aff *pa, |
| __isl_take isl_point *pnt); |
| |
| #include <isl/polynomial.h> |
| __isl_give isl_val *isl_pw_qpolynomial_eval( |
| __isl_take isl_pw_qpolynomial *pwqp, |
| __isl_take isl_point *pnt); |
| __isl_give isl_val *isl_pw_qpolynomial_fold_eval( |
| __isl_take isl_pw_qpolynomial_fold *pwf, |
| __isl_take isl_point *pnt); |
| __isl_give isl_val *isl_union_pw_qpolynomial_eval( |
| __isl_take isl_union_pw_qpolynomial *upwqp, |
| __isl_take isl_point *pnt); |
| __isl_give isl_val *isl_union_pw_qpolynomial_fold_eval( |
| __isl_take isl_union_pw_qpolynomial_fold *upwf, |
| __isl_take isl_point *pnt); |
| |
| These functions return NaN when evaluated at a void point. |
| Note that C<isl_pw_aff_eval> returns NaN when the function is evaluated outside |
| its definition domain, while C<isl_pw_qpolynomial_eval> returns zero |
| when the function is evaluated outside its explicit domain. |
| |
| =item * Dimension manipulation |
| |
| It is usually not advisable to directly change the (input or output) |
| space of a set or a relation as this removes the name and the internal |
| structure of the space. However, the functions below can be useful |
| to add new parameters, assuming |
| C<isl_set_align_params> and C<isl_map_align_params> |
| are not sufficient. |
| |
| #include <isl/space.h> |
| __isl_give isl_space *isl_space_add_dims( |
| __isl_take isl_space *space, |
| enum isl_dim_type type, unsigned n); |
| __isl_give isl_space *isl_space_insert_dims( |
| __isl_take isl_space *space, |
| enum isl_dim_type type, unsigned pos, unsigned n); |
| __isl_give isl_space *isl_space_drop_dims( |
| __isl_take isl_space *space, |
| enum isl_dim_type type, unsigned first, unsigned n); |
| __isl_give isl_space *isl_space_move_dims( |
| __isl_take isl_space *space, |
| enum isl_dim_type dst_type, unsigned dst_pos, |
| enum isl_dim_type src_type, unsigned src_pos, |
| unsigned n); |
| |
| #include <isl/local_space.h> |
| __isl_give isl_local_space *isl_local_space_add_dims( |
| __isl_take isl_local_space *ls, |
| enum isl_dim_type type, unsigned n); |
| __isl_give isl_local_space *isl_local_space_insert_dims( |
| __isl_take isl_local_space *ls, |
| enum isl_dim_type type, unsigned first, unsigned n); |
| __isl_give isl_local_space *isl_local_space_drop_dims( |
| __isl_take isl_local_space *ls, |
| enum isl_dim_type type, unsigned first, unsigned n); |
| |
| #include <isl/set.h> |
| __isl_give isl_basic_set *isl_basic_set_add_dims( |
| __isl_take isl_basic_set *bset, |
| enum isl_dim_type type, unsigned n); |
| __isl_give isl_set *isl_set_add_dims( |
| __isl_take isl_set *set, |
| 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_set *isl_set_insert_dims( |
| __isl_take isl_set *set, |
| enum isl_dim_type type, unsigned pos, unsigned n); |
| __isl_give isl_basic_set *isl_basic_set_move_dims( |
| __isl_take isl_basic_set *bset, |
| enum isl_dim_type dst_type, unsigned dst_pos, |
| enum isl_dim_type src_type, unsigned src_pos, |
| unsigned n); |
| __isl_give isl_set *isl_set_move_dims( |
| __isl_take isl_set *set, |
| enum isl_dim_type dst_type, unsigned dst_pos, |
| enum isl_dim_type src_type, unsigned src_pos, |
| unsigned n); |
| |
| #include <isl/map.h> |
| __isl_give isl_basic_map *isl_basic_map_add_dims( |
| __isl_take isl_basic_map *bmap, |
| enum isl_dim_type type, unsigned n); |
| __isl_give isl_map *isl_map_add_dims( |
| __isl_take isl_map *map, |
| enum isl_dim_type type, 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_map *isl_map_insert_dims( |
| __isl_take isl_map *map, |
| enum isl_dim_type type, unsigned pos, unsigned n); |
| __isl_give isl_basic_map *isl_basic_map_move_dims( |
| __isl_take isl_basic_map *bmap, |
| enum isl_dim_type dst_type, unsigned dst_pos, |
| enum isl_dim_type src_type, unsigned src_pos, |
| unsigned n); |
| __isl_give isl_map *isl_map_move_dims( |
| __isl_take isl_map *map, |
| enum isl_dim_type dst_type, unsigned dst_pos, |
| enum isl_dim_type src_type, unsigned src_pos, |
| unsigned n); |
| |
| #include <isl/val.h> |
| __isl_give isl_multi_val *isl_multi_val_insert_dims( |
| __isl_take isl_multi_val *mv, |
| enum isl_dim_type type, unsigned first, unsigned n); |
| __isl_give isl_multi_val *isl_multi_val_add_dims( |
| __isl_take isl_multi_val *mv, |
| enum isl_dim_type type, unsigned n); |
| __isl_give isl_multi_val *isl_multi_val_drop_dims( |
| __isl_take isl_multi_val *mv, |
| enum isl_dim_type type, unsigned first, unsigned n); |
| |
| #include <isl/aff.h> |
| __isl_give isl_aff *isl_aff_insert_dims( |
| __isl_take isl_aff *aff, |
| enum isl_dim_type type, unsigned first, unsigned n); |
| __isl_give isl_multi_aff *isl_multi_aff_insert_dims( |
| __isl_take isl_multi_aff *ma, |
| enum isl_dim_type type, unsigned first, unsigned n); |
| __isl_give isl_pw_aff *isl_pw_aff_insert_dims( |
| __isl_take isl_pw_aff *pwaff, |
| enum isl_dim_type type, unsigned first, unsigned n); |
| __isl_give isl_multi_pw_aff *isl_multi_pw_aff_insert_dims( |
| __isl_take isl_multi_pw_aff *mpa, |
| enum isl_dim_type type, unsigned first, unsigned n); |
| __isl_give isl_aff *isl_aff_add_dims( |
| __isl_take isl_aff *aff, |
| enum isl_dim_type type, unsigned n); |
| __isl_give isl_multi_aff *isl_multi_aff_add_dims( |
| __isl_take isl_multi_aff *ma, |
| enum isl_dim_type type, unsigned n); |
| __isl_give isl_pw_aff *isl_pw_aff_add_dims( |
| __isl_take isl_pw_aff *pwaff, |
| enum isl_dim_type type, unsigned n); |
| __isl_give isl_multi_pw_aff *isl_multi_pw_aff_add_dims( |
| __isl_take isl_multi_pw_aff *mpa, |
| enum isl_dim_type type, unsigned n); |
| __isl_give isl_aff *isl_aff_drop_dims( |
| __isl_take isl_aff *aff, |
| enum isl_dim_type type, unsigned first, unsigned n); |
| __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_aff *isl_pw_aff_drop_dims( |
| __isl_take isl_pw_aff *pwaff, |
| 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); |
| __isl_give isl_union_pw_aff *isl_union_pw_aff_drop_dims( |
| __isl_take isl_union_pw_aff *upa, |
| enum isl_dim_type type, unsigned first, unsigned n); |
| __isl_give isl_union_pw_multi_aff * |
| isl_union_pw_multi_aff_drop_dims( |
| __isl_take isl_union_pw_multi_aff *upma, |
| enum isl_dim_type type, |
| unsigned first, unsigned n); |
| __isl_give isl_multi_union_pw_aff * |
| isl_multi_union_pw_aff_drop_dims( |
| __isl_take isl_multi_union_pw_aff *mupa, |
| enum isl_dim_type type, unsigned first, |
| unsigned n); |
| __isl_give isl_aff *isl_aff_move_dims( |
| __isl_take isl_aff *aff, |
| enum isl_dim_type dst_type, unsigned dst_pos, |
| enum isl_dim_type src_type, unsigned src_pos, |
| unsigned n); |
| __isl_give isl_multi_aff *isl_multi_aff_move_dims( |
| __isl_take isl_multi_aff *ma, |
| enum isl_dim_type dst_type, unsigned dst_pos, |
| enum isl_dim_type src_type, unsigned src_pos, |
| unsigned n); |
| __isl_give isl_pw_aff *isl_pw_aff_move_dims( |
| __isl_take isl_pw_aff *pa, |
| enum isl_dim_type dst_type, unsigned dst_pos, |
| enum isl_dim_type src_type, unsigned src_pos, |
| unsigned n); |
| __isl_give isl_multi_pw_aff *isl_multi_pw_aff_move_dims( |
| __isl_take isl_multi_pw_aff *pma, |
| enum isl_dim_type dst_type, unsigned dst_pos, |
| enum isl_dim_type src_type, unsigned src_pos, |
| unsigned n); |
| |
| #include <isl/polynomial.h> |
| __isl_give isl_union_pw_qpolynomial * |
| isl_union_pw_qpolynomial_drop_dims( |
| __isl_take isl_union_pw_qpolynomial *upwqp, |
| enum isl_dim_type type, |
| unsigned first, unsigned n); |
| __isl_give isl_union_pw_qpolynomial_fold * |
| isl_union_pw_qpolynomial_fold_drop_dims( |
| __isl_take isl_union_pw_qpolynomial_fold *upwf, |
| enum isl_dim_type type, |
| unsigned first, unsigned n); |
| |
| The operations on union expressions can only manipulate parameters. |
| |
| =back |
| |
| =head2 Binary Operations |
| |
| The two arguments of a binary operation not only need to live |
| in the same C<isl_ctx>, they currently also need to have |
| the same (number of) parameters. |
| |
| =head3 Basic Operations |
| |
| =over |
| |
| =item * Intersection |
| |
| #include <isl/local_space.h> |
| __isl_give isl_local_space *isl_local_space_intersect( |
| __isl_take isl_local_space *ls1, |
| __isl_take isl_local_space *ls2); |
| |
| #include <isl/set.h> |
| __isl_give isl_basic_set *isl_basic_set_intersect_params( |
| __isl_take isl_basic_set *bset1, |
| __isl_take isl_basic_set *bset2); |
| __isl_give isl_basic_set *isl_basic_set_intersect( |
| __isl_take isl_basic_set *bset1, |
| __isl_take isl_basic_set *bset2); |
| __isl_give isl_basic_set *isl_basic_set_list_intersect( |
| __isl_take struct isl_basic_set_list *list); |
| __isl_give isl_set *isl_set_intersect_params( |
| __isl_take isl_set *set, |
| __isl_take isl_set *params); |
| __isl_give isl_set *isl_set_intersect( |
| __isl_take isl_set *set1, |
| __isl_take isl_set *set2); |
| |
| #include <isl/map.h> |
| __isl_give isl_basic_map *isl_basic_map_intersect_domain( |
| __isl_take isl_basic_map *bmap, |
| __isl_take isl_basic_set *bset); |
| __isl_give isl_basic_map *isl_basic_map_intersect_range( |
| __isl_take isl_basic_map *bmap, |
| __isl_take isl_basic_set *bset); |
| __isl_give isl_basic_map *isl_basic_map_intersect( |
| __isl_take isl_basic_map *bmap1, |
| __isl_take isl_basic_map *bmap2); |
| __isl_give isl_basic_map *isl_basic_map_list_intersect( |
| __isl_take isl_basic_map_list *list); |
| __isl_give isl_map *isl_map_intersect_params( |
| __isl_take isl_map *map, |
| __isl_take isl_set *params); |
| __isl_give isl_map *isl_map_intersect_domain( |
| __isl_take isl_map *map, |
| __isl_take isl_set *set); |
| __isl_give isl_map *isl_map_intersect_range( |
| __isl_take isl_map *map, |
| __isl_take isl_set *set); |
| __isl_give isl_map *isl_map_intersect( |
| __isl_take isl_map *map1, |
| __isl_take isl_map *map2); |
| __isl_give isl_map * |
| isl_map_intersect_domain_factor_range( |
| __isl_take isl_map *map, |
| __isl_take isl_map *factor); |
| __isl_give isl_map * |
| isl_map_intersect_range_factor_range( |
| __isl_take isl_map *map, |
| __isl_take isl_map *factor); |
| |
| #include <isl/union_set.h> |
| __isl_give isl_union_set *isl_union_set_intersect_params( |
| __isl_take isl_union_set *uset, |
| __isl_take isl_set *set); |
| __isl_give isl_union_set *isl_union_set_intersect( |
| __isl_take isl_union_set *uset1, |
| __isl_take isl_union_set *uset2); |
| |
| #include <isl/union_map.h> |
| __isl_give isl_union_map *isl_union_map_intersect_params( |
| __isl_take isl_union_map *umap, |
| __isl_take isl_set *set); |
| __isl_give isl_union_map *isl_union_map_intersect_domain( |
| __isl_take isl_union_map *umap, |
| __isl_take isl_union_set *uset); |
| __isl_give isl_union_map *isl_union_map_intersect_range( |
| __isl_take isl_union_map *umap, |
| __isl_take isl_union_set *uset); |
| __isl_give isl_union_map *isl_union_map_intersect( |
| __isl_take isl_union_map *umap1, |
| __isl_take isl_union_map *umap2); |
| __isl_give isl_union_map * |
| isl_union_map_intersect_range_factor_range( |
| __isl_take isl_union_map *umap, |
| __isl_take isl_union_map *factor); |
| |
| #include <isl/aff.h> |
| __isl_give isl_pw_aff *isl_pw_aff_intersect_domain( |
| __isl_take isl_pw_aff *pa, |
| __isl_take isl_set *set); |
| __isl_give isl_multi_pw_aff * |
| isl_multi_pw_aff_intersect_domain( |
| __isl_take isl_multi_pw_aff *mpa, |
| __isl_take isl_set *domain); |
| __isl_give isl_pw_multi_aff *isl_pw_multi_aff_intersect_domain( |
| __isl_take isl_pw_multi_aff *pma, |
| __isl_take isl_set *set); |
| __isl_give isl_union_pw_aff *isl_union_pw_aff_intersect_domain( |
| __isl_take isl_union_pw_aff *upa, |
| __isl_take isl_union_set *uset); |
| __isl_give isl_union_pw_multi_aff * |
| isl_union_pw_multi_aff_intersect_domain( |
| __isl_take isl_union_pw_multi_aff *upma, |
| __isl_take isl_union_set *uset); |
| __isl_give isl_multi_union_pw_aff * |
| isl_multi_union_pw_aff_intersect_domain( |
| __isl_take isl_multi_union_pw_aff *mupa, |
| __isl_take isl_union_set *uset); |
| __isl_give isl_pw_aff *isl_pw_aff_intersect_params( |
| __isl_take isl_pw_aff *pa, |
| __isl_take isl_set *set); |
| __isl_give isl_multi_pw_aff * |
| isl_multi_pw_aff_intersect_params( |
| __isl_take isl_multi_pw_aff *mpa, |
| __isl_take isl_set *set); |
| __isl_give isl_pw_multi_aff *isl_pw_multi_aff_intersect_params( |
| __isl_take isl_pw_multi_aff *pma, |
| __isl_take isl_set *set); |
| __isl_give isl_union_pw_aff * |
| isl_union_pw_aff_intersect_params( |
| __isl_take isl_union_pw_aff *upa, |
| __isl_give isl_union_pw_multi_aff * |
| isl_union_pw_multi_aff_intersect_params( |
| __isl_take isl_union_pw_multi_aff *upma, |
| __isl_take isl_set *set); |
| __isl_give isl_multi_union_pw_aff * |
| isl_multi_union_pw_aff_intersect_params( |
| __isl_take isl_multi_union_pw_aff *mupa, |
| __isl_take isl_set *params); |
| isl_multi_union_pw_aff_intersect_range( |
| __isl_take isl_multi_union_pw_aff *mupa, |
| __isl_take isl_set *set); |
| |
| #include <isl/polynomial.h> |
| __isl_give isl_pw_qpolynomial * |
| isl_pw_qpolynomial_intersect_domain( |
| __isl_take isl_pw_qpolynomial *pwpq, |
| __isl_take isl_set *set); |
| __isl_give isl_union_pw_qpolynomial * |
| isl_union_pw_qpolynomial_intersect_domain( |
| __isl_take isl_union_pw_qpolynomial *upwpq, |
| __isl_take isl_union_set *uset); |
| __isl_give isl_union_pw_qpolynomial_fold * |
| isl_union_pw_qpolynomial_fold_intersect_domain( |
| __isl_take isl_union_pw_qpolynomial_fold *upwf, |
| __isl_take isl_union_set *uset); |
| __isl_give isl_pw_qpolynomial * |
| isl_pw_qpolynomial_intersect_params( |
| __isl_take isl_pw_qpolynomial *pwpq, |
| __isl_take isl_set *set); |
| __isl_give isl_pw_qpolynomial_fold * |
| isl_pw_qpolynomial_fold_intersect_params( |
| __isl_take isl_pw_qpolynomial_fold *pwf, |
| __isl_take isl_set *set); |
| __isl_give isl_union_pw_qpolynomial * |
| isl_union_pw_qpolynomial_intersect_params( |
| __isl_take isl_union_pw_qpolynomial *upwpq, |
| __isl_take isl_set *set); |
| __isl_give isl_union_pw_qpolynomial_fold * |
| isl_union_pw_qpolynomial_fold_intersect_params( |
| __isl_take isl_union_pw_qpolynomial_fold *upwf, |
| __isl_take isl_set *set); |
| |
| 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. |
| The list passed to C<isl_basic_set_list_intersect> needs to have |
| at least one element and all elements need to live in the same space. |
| The function C<isl_multi_union_pw_aff_intersect_range> |
| restricts the input function to those shared domain elements |
| that map to the specified range. |
| |
| =item * Union |
| |
| #include <isl/set.h> |
| __isl_give isl_set *isl_basic_set_union( |
| __isl_take isl_basic_set *bset1, |
| __isl_take isl_basic_set *bset2); |
| __isl_give isl_set *isl_set_union( |
| __isl_take isl_set *set1, |
| __isl_take isl_set *set2); |
| __isl_give isl_set *isl_set_list_union( |
| __isl_take isl_set_list *list); |
| |
| #include <isl/map.h> |
| __isl_give isl_map *isl_basic_map_union( |
| __isl_take isl_basic_map *bmap1, |
| __isl_take isl_basic_map *bmap2); |
| __isl_give isl_map *isl_map_union( |
| __isl_take isl_map *map1, |
| __isl_take isl_map *map2); |
| |
| #include <isl/union_set.h> |
| __isl_give isl_union_set *isl_union_set_union( |
| __isl_take isl_union_set *uset1, |
| __isl_take isl_union_set *uset2); |
| __isl_give isl_union_set *isl_union_set_list_union( |
| __isl_take isl_union_set_list *list); |
| |
| #include <isl/union_map.h> |
| __isl_give isl_union_map *isl_union_map_union( |
| __isl_take isl_union_map *umap1, |
| __isl_take isl_union_map *umap2); |
| |
| The list passed to C<isl_set_list_union> needs to have |
| at least one element and all elements need to live in the same space. |
| |
| =item * Set difference |
| |
| #include <isl/set.h> |
| __isl_give isl_set *isl_set_subtract( |
| __isl_take isl_set *set1, |
| __isl_take isl_set *set2); |
| |
| #include <isl/map.h> |
| __isl_give isl_map *isl_map_subtract( |
| __isl_take isl_map *map1, |
| __isl_take isl_map *map2); |
| __isl_give isl_map *isl_map_subtract_domain( |
| __isl_take isl_map *map, |
| __isl_take isl_set *dom); |
| __isl_give isl_map *isl_map_subtract_range( |
| __isl_take isl_map *map, |
| __isl_take isl_set *dom); |
| |
| #include <isl/union_set.h> |
| __isl_give isl_union_set *isl_union_set_subtract( |
| __isl_take isl_union_set *uset1, |
| __isl_take isl_union_set *uset2); |
| |
| #include <isl/union_map.h> |
| __isl_give isl_union_map *isl_union_map_subtract( |
| __isl_take isl_union_map *umap1, |
| __isl_take isl_union_map *umap2); |
| __isl_give isl_union_map *isl_union_map_subtract_domain( |
| __isl_take isl_union_map *umap, |
| __isl_take isl_union_set *dom); |
| __isl_give isl_union_map *isl_union_map_subtract_range( |
| __isl_take isl_union_map *umap, |
| __isl_take isl_union_set *dom); |
| |
| #include <isl/aff.h> |
| __isl_give isl_pw_aff *isl_pw_aff_subtract_domain( |
| __isl_take isl_pw_aff *pa, |
| __isl_take isl_set *set); |
| __isl_give isl_pw_multi_aff * |
| isl_pw_multi_aff_subtract_domain( |
| __isl_take isl_pw_multi_aff *pma, |
| __isl_take isl_set *set); |
| __isl_give isl_union_pw_aff * |
| isl_union_pw_aff_subtract_domain( |
| __isl_take isl_union_pw_aff *upa, |
| __isl_take isl_union_set *uset); |
| __isl_give isl_union_pw_multi_aff * |
| isl_union_pw_multi_aff_subtract_domain( |
| __isl_take isl_union_pw_multi_aff *upma, |
| __isl_take isl_set *set); |
| |
| #include <isl/polynomial.h> |
| __isl_give isl_pw_qpolynomial * |
| isl_pw_qpolynomial_subtract_domain( |
| __isl_take isl_pw_qpolynomial *pwpq, |
| __isl_take isl_set *set); |
| __isl_give isl_pw_qpolynomial_fold * |
| isl_pw_qpolynomial_fold_subtract_domain( |
| __isl_take isl_pw_qpolynomial_fold *pwf, |
| __isl_take isl_set *set); |
| __isl_give isl_union_pw_qpolynomial * |
| isl_union_pw_qpolynomial_subtract_domain( |
| __isl_take isl_union_pw_qpolynomial *upwpq, |
| __isl_take isl_union_set *uset); |
| __isl_give isl_union_pw_qpolynomial_fold * |
| isl_union_pw_qpolynomial_fold_subtract_domain( |
| __isl_take isl_union_pw_qpolynomial_fold *upwf, |
| __isl_take isl_union_set *uset); |
| |
| =item * Application |
| |
| #include <isl/space.h> |
| __isl_give isl_space *isl_space_join( |
| __isl_take isl_space *left, |
| __isl_take isl_space *right); |
| |
| #include <isl/map.h> |
| __isl_give isl_basic_set *isl_basic_set_apply( |
| __isl_take isl_basic_set *bset, |
| __isl_take isl_basic_map *bmap); |
| __isl_give isl_set *isl_set_apply( |
| __isl_take isl_set *set, |
| __isl_take isl_map *map); |
| __isl_give isl_union_set *isl_union_set_apply( |
| __isl_take isl_union_set *uset, |
| __isl_take isl_union_map *umap); |
| __isl_give isl_basic_map *isl_basic_map_apply_domain( |
| __isl_take isl_basic_map *bmap1, |
| __isl_take isl_basic_map *bmap2); |
| __isl_give isl_basic_map *isl_basic_map_apply_range( |
| __isl_take isl_basic_map *bmap1, |
| __isl_take isl_basic_map *bmap2); |
| __isl_give isl_map *isl_map_apply_domain( |
| __isl_take isl_map *map1, |
| __isl_take isl_map *map2); |
| __isl_give isl_map *isl_map_apply_range( |
| __isl_take isl_map *map1, |
| __isl_take isl_map *map2); |
| |
| #include <isl/union_map.h> |
| __isl_give isl_union_map *isl_union_map_apply_domain( |
| __isl_take isl_union_map *umap1, |
| __isl_take isl_union_map *umap2); |
| __isl_give isl_union_map *isl_union_map_apply_range( |
| __isl_take isl_union_map *umap1, |
| __isl_take isl_union_map *umap2); |
| |
| #include <isl/aff.h> |
| __isl_give isl_union_pw_aff * |
| isl_multi_union_pw_aff_apply_aff( |
| __isl_take isl_multi_union_pw_aff *mupa, |
| __isl_take isl_aff *aff); |
| __isl_give isl_union_pw_aff * |
| isl_multi_union_pw_aff_apply_pw_aff( |
| __isl_take isl_multi_union_pw_aff *mupa, |
| __isl_take isl_pw_aff *pa); |
| __isl_give isl_multi_union_pw_aff * |
| isl_multi_union_pw_aff_apply_multi_aff( |
| __isl_take isl_multi_union_pw_aff *mupa, |
| __isl_take isl_multi_aff *ma); |
| __isl_give isl_multi_union_pw_aff * |
| isl_multi_union_pw_aff_apply_pw_multi_aff( |
| __isl_take isl_multi_union_pw_aff *mupa, |
| __isl_take isl_pw_multi_aff *pma); |
| |
| The result of C<isl_multi_union_pw_aff_apply_aff> is defined |
| over the shared domain of the elements of the input. The dimension is |
| required to be greater than zero. |
| The C<isl_multi_union_pw_aff> argument of |
| C<isl_multi_union_pw_aff_apply_multi_aff> is allowed to be zero-dimensional, |
| but only if the range of the C<isl_multi_aff> argument |
| is also zero-dimensional. |
| Similarly for C<isl_multi_union_pw_aff_apply_pw_multi_aff>. |
| |
| #include <isl/polynomial.h> |
| __isl_give isl_pw_qpolynomial_fold * |
| isl_set_apply_pw_qpolynomial_fold( |
| __isl_take isl_set *set, |
| __isl_take isl_pw_qpolynomial_fold *pwf, |
| int *tight); |
| __isl_give isl_pw_qpolynomial_fold * |
| isl_map_apply_pw_qpolynomial_fold( |
| __isl_take isl_map *map, |
| __isl_take isl_pw_qpolynomial_fold *pwf, |
| int *tight); |
| __isl_give isl_union_pw_qpolynomial_fold * |
| isl_union_set_apply_union_pw_qpolynomial_fold( |
| __isl_take isl_union_set *uset, |
| __isl_take isl_union_pw_qpolynomial_fold *upwf, |
| int *tight); |
| __isl_give isl_union_pw_qpolynomial_fold * |
| isl_union_map_apply_union_pw_qpolynomial_fold( |
| __isl_take isl_union_map *umap, |
| __isl_take isl_union_pw_qpolynomial_fold *upwf, |
| int *tight); |
| |
| The functions taking a map |
| compose the given map with the given piecewise quasipolynomial reduction. |
| That is, compute a bound (of the same type as C<pwf> or C<upwf> itself) |
| over all elements in the intersection of the range of the map |
| and the domain of the piecewise quasipolynomial reduction |
| as a function of an element in the domain of the map. |
| The functions taking a set compute a bound over all elements in the |
| intersection of the set and the domain of the |
| piecewise quasipolynomial reduction. |
| |
| =item * Preimage |
| |
| #include <isl/set.h> |
| __isl_give isl_basic_set * |
| isl_basic_set_preimage_multi_aff( |
| __isl_take isl_basic_set *bset, |
| __isl_take isl_multi_aff *ma); |
| __isl_give isl_set *isl_set_preimage_multi_aff( |
| __isl_take isl_set *set, |
| __isl_take isl_multi_aff *ma); |
| __isl_give isl_set *isl_set_preimage_pw_multi_aff( |
| __isl_take isl_set *set, |
| __isl_take isl_pw_multi_aff *pma); |
| __isl_give isl_set *isl_set_preimage_multi_pw_aff( |
| __isl_take isl_set *set, |
| __isl_take isl_multi_pw_aff *mpa); |
| |
| #include <isl/union_set.h> |
| __isl_give isl_union_set * |
| isl_union_set_preimage_multi_aff( |
| __isl_take isl_union_set *uset, |
| __isl_take isl_multi_aff *ma); |
| __isl_give isl_union_set * |
| isl_union_set_preimage_pw_multi_aff( |
| __isl_take isl_union_set *uset, |
| __isl_take isl_pw_multi_aff *pma); |
| __isl_give isl_union_set * |
| isl_union_set_preimage_union_pw_multi_aff( |
| __isl_take isl_union_set *uset, |
| __isl_take isl_union_pw_multi_aff *upma); |
| |
| #include <isl/map.h> |
| __isl_give isl_basic_map * |
| isl_basic_map_preimage_domain_multi_aff( |
| __isl_take isl_basic_map *bmap, |
| __isl_take isl_multi_aff *ma); |
| __isl_give isl_map *isl_map_preimage_domain_multi_aff( |
| __isl_take isl_map *map, |
| __isl_take isl_multi_aff *ma); |
| __isl_give isl_map *isl_map_preimage_range_multi_aff( |
| __isl_take isl_map *map, |
| __isl_take isl_multi_aff *ma); |
| __isl_give isl_map * |
| isl_map_preimage_domain_pw_multi_aff( |
| __isl_take isl_map *map, |
| __isl_take isl_pw_multi_aff *pma); |
| __isl_give isl_map * |
| isl_map_preimage_range_pw_multi_aff( |
| __isl_take isl_map *map, |
| __isl_take isl_pw_multi_aff *pma); |
| __isl_give isl_map * |
| isl_map_preimage_domain_multi_pw_aff( |
| __isl_take isl_map *map, |
| __isl_take isl_multi_pw_aff *mpa); |
| __isl_give isl_basic_map * |
| isl_basic_map_preimage_range_multi_aff( |
| __isl_take isl_basic_map *bmap, |
| __isl_take isl_multi_aff *ma); |
| |
| #include <isl/union_map.h> |
| __isl_give isl_union_map * |
| isl_union_map_preimage_domain_multi_aff( |
| __isl_take isl_union_map *umap, |
| __isl_take isl_multi_aff *ma); |
| __isl_give isl_union_map * |
| isl_union_map_preimage_range_multi_aff( |
| __isl_take isl_union_map *umap, |
| __isl_take isl_multi_aff *ma); |
| __isl_give isl_union_map * |
| isl_union_map_preimage_domain_pw_multi_aff( |
| __isl_take isl_union_map *umap, |
| __isl_take isl_pw_multi_aff *pma); |
| __isl_give isl_union_map * |
| isl_union_map_preimage_range_pw_multi_aff( |
| __isl_take isl_union_map *umap, |
| __isl_take isl_pw_multi_aff *pma); |
| __isl_give isl_union_map * |
| isl_union_map_preimage_domain_union_pw_multi_aff( |
| __isl_take isl_union_map *umap, |
| __isl_take isl_union_pw_multi_aff *upma); |
| __isl_give isl_union_map * |
| isl_union_map_preimage_range_union_pw_multi_aff( |
| __isl_take isl_union_map *umap, |
| __isl_take isl_union_pw_multi_aff *upma); |
| |
| These functions compute the preimage of the given set or map domain/range under |
| the given function. In other words, the expression is plugged |
| into the set description or into the domain/range of the map. |
| |
| =item * Pullback |
| |
| #include <isl/aff.h> |
| __isl_give isl_aff *isl_aff_pullback_aff( |
| __isl_take isl_aff *aff1, |
| __isl_take isl_aff *aff2); |
| __isl_give isl_aff *isl_aff_pullback_multi_aff( |
| __isl_take isl_aff *aff, |
| __isl_take isl_multi_aff *ma); |
| __isl_give isl_pw_aff *isl_pw_aff_pullback_multi_aff( |
| __isl_take isl_pw_aff *pa, |
| __isl_take isl_multi_aff *ma); |
| __isl_give isl_pw_aff *isl_pw_aff_pullback_pw_multi_aff( |
| __isl_take isl_pw_aff *pa, |
| __isl_take isl_pw_multi_aff *pma); |
| __isl_give isl_pw_aff *isl_pw_aff_pullback_multi_pw_aff( |
| __isl_take isl_pw_aff *pa, |
| __isl_take isl_multi_pw_aff *mpa); |
| __isl_give isl_multi_aff *isl_multi_aff_pullback_multi_aff( |
| __isl_take isl_multi_aff *ma1, |
| __isl_take isl_multi_aff *ma2); |
| __isl_give isl_pw_multi_aff * |
| isl_pw_multi_aff_pullback_multi_aff( |
| __isl_take isl_pw_multi_aff *pma, |
| __isl_take isl_multi_aff *ma); |
| __isl_give isl_multi_pw_aff * |
| isl_multi_pw_aff_pullback_multi_aff( |
| __isl_take isl_multi_pw_aff *mpa, |
| __isl_take isl_multi_aff *ma); |
| __isl_give isl_pw_multi_aff * |
| isl_pw_multi_aff_pullback_pw_multi_aff( |
| __isl_take isl_pw_multi_aff *pma1, |
| __isl_take isl_pw_multi_aff *pma2); |
| __isl_give isl_multi_pw_aff * |
| isl_multi_pw_aff_pullback_pw_multi_aff( |
| __isl_take isl_multi_pw_aff *mpa, |
| __isl_take isl_pw_multi_aff *pma); |
| __isl_give isl_multi_pw_aff * |
| isl_multi_pw_aff_pullback_multi_pw_aff( |
| __isl_take isl_multi_pw_aff *mpa1, |
| __isl_take isl_multi_pw_aff *mpa2); |
| __isl_give isl_union_pw_aff * |
| isl_union_pw_aff_pullback_union_pw_multi_aff( |
| __isl_take isl_union_pw_aff *upa, |
| __isl_take isl_union_pw_multi_aff *upma); |
| __isl_give isl_union_pw_multi_aff * |
| isl_union_pw_multi_aff_pullback_union_pw_multi_aff( |
| __isl_take isl_union_pw_multi_aff *upma1, |
| __isl_take isl_union_pw_multi_aff *upma2); |
| __isl_give isl_multi_union_pw_aff * |
| isl_multi_union_pw_aff_pullback_union_pw_multi_aff( |
| __isl_take isl_multi_union_pw_aff *mupa, |
| __isl_take isl_union_pw_multi_aff *upma); |
| |
| These functions precompose the first expression by the second function. |
| In other words, the second function is plugged |
| into the first expression. |
| |
| =item * Locus |
| |
| #include <isl/aff.h> |
| __isl_give isl_basic_set *isl_aff_eq_basic_set( |
| __isl_take isl_aff *aff1, |
| __isl_take isl_aff *aff2); |
| __isl_give isl_set *isl_aff_eq_set( |
| __isl_take isl_aff *aff1, |
| __isl_take isl_aff *aff2); |
| __isl_give isl_set *isl_aff_ne_set( |
| __isl_take isl_aff *aff1, |
| __isl_take isl_aff *aff2); |
| __isl_give isl_basic_set *isl_aff_le_basic_set( |
| __isl_take isl_aff *aff1, |
| __isl_take isl_aff *aff2); |
| __isl_give isl_set *isl_aff_le_set( |
| __isl_take isl_aff *aff1, |
| __isl_take isl_aff *aff2); |
| __isl_give isl_basic_set *isl_aff_lt_basic_set( |
| __isl_take isl_aff *aff1, |
| __isl_take isl_aff *aff2); |
| __isl_give isl_set *isl_aff_lt_set( |
| __isl_take isl_aff *aff1, |
| __isl_take isl_aff *aff2); |
| __isl_give isl_basic_set *isl_aff_ge_basic_set( |
| __isl_take isl_aff *aff1, |
| __isl_take isl_aff *aff2); |
| __isl_give isl_set *isl_aff_ge_set( |
| __isl_take isl_aff *aff1, |
| __isl_take isl_aff *aff2); |
| __isl_give isl_basic_set *isl_aff_gt_basic_set( |
| __isl_take isl_aff *aff1, |
| __isl_take isl_aff *aff2); |
| __isl_give isl_set *isl_aff_gt_set( |
| __isl_take isl_aff *aff1, |
| __isl_take isl_aff *aff2); |
| __isl_give isl_set *isl_pw_aff_eq_set( |
| __isl_take isl_pw_aff *pwaff1, |
| __isl_take isl_pw_aff *pwaff2); |
| __isl_give isl_set *isl_pw_aff_ne_set( |
| __isl_take isl_pw_aff *pwaff1, |
| __isl_take isl_pw_aff *pwaff2); |
| __isl_give isl_set *isl_pw_aff_le_set( |
| __isl_take isl_pw_aff *pwaff1, |
| __isl_take isl_pw_aff *pwaff2); |
| __isl_give isl_set *isl_pw_aff_lt_set( |
| __isl_take isl_pw_aff *pwaff1, |
| __isl_take isl_pw_aff *pwaff2); |
| __isl_give isl_set *isl_pw_aff_ge_set( |
| __isl_take isl_pw_aff *pwaff1, |
| __isl_take isl_pw_aff *pwaff2); |
| __isl_give isl_set *isl_pw_aff_gt_set( |
| __isl_take isl_pw_aff *pwaff1, |
| __isl_take isl_pw_aff *pwaff2); |
| |
| __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_lt_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); |
| __isl_give isl_set *isl_multi_aff_lex_gt_set( |
| __isl_take isl_multi_aff *ma1, |
| __isl_take isl_multi_aff *ma2); |
| |
| __isl_give isl_set *isl_pw_aff_list_eq_set( |
| __isl_take isl_pw_aff_list *list1, |
| __isl_take isl_pw_aff_list *list2); |
| __isl_give isl_set *isl_pw_aff_list_ne_set( |
| __isl_take isl_pw_aff_list *list1, |
| __isl_take isl_pw_aff_list *list2); |
| __isl_give isl_set *isl_pw_aff_list_le_set( |
| __isl_take isl_pw_aff_list *list1, |
| __isl_take isl_pw_aff_list *list2); |
| __isl_give isl_set *isl_pw_aff_list_lt_set( |
| __isl_take isl_pw_aff_list *list1, |
| __isl_take isl_pw_aff_list *list2); |
| __isl_give isl_set *isl_pw_aff_list_ge_set( |
| __isl_take isl_pw_aff_list *list1, |
| __isl_take isl_pw_aff_list *list2); |
| __isl_give isl_set *isl_pw_aff_list_gt_set( |
| __isl_take isl_pw_aff_list *list1, |
| __isl_take isl_pw_aff_list *list2); |
| |
| 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>. |
| The function C<isl_pw_aff_ge_set> returns a set |
| containing those elements in the shared domain |
| of C<pwaff1> and C<pwaff2> where C<pwaff1> is |
| greater than or equal to C<pwaff2>. |
| 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>. |
| The functions operating on C<isl_pw_aff_list> apply the corresponding |
| C<isl_pw_aff> function to each pair of elements in the two lists. |
| |
| #include <isl/aff.h> |
| __isl_give isl_map *isl_pw_aff_eq_map( |
| __isl_take isl_pw_aff *pa1, |
| __isl_take isl_pw_aff *pa2); |
| __isl_give isl_map *isl_pw_aff_lt_map( |
| __isl_take isl_pw_aff *pa1, |
| __isl_take isl_pw_aff *pa2); |
| __isl_give isl_map *isl_pw_aff_gt_map( |
| __isl_take isl_pw_aff *pa1, |
| __isl_take isl_pw_aff *pa2); |
| |
| __isl_give isl_map *isl_multi_pw_aff_eq_map( |
| __isl_take isl_multi_pw_aff *mpa1, |
| __isl_take isl_multi_pw_aff *mpa2); |
| __isl_give isl_map *isl_multi_pw_aff_lex_lt_map( |
| __isl_take isl_multi_pw_aff *mpa1, |
| __isl_take isl_multi_pw_aff *mpa2); |
| __isl_give isl_map *isl_multi_pw_aff_lex_gt_map( |
| __isl_take isl_multi_pw_aff *mpa1, |
| __isl_take isl_multi_pw_aff *mpa2); |
| |
| These functions return a map between domain elements of the arguments |
| where the function values satisfy the given relation. |
| |
| #include <isl/union_map.h> |
| __isl_give isl_union_map * |
| isl_union_map_eq_at_multi_union_pw_aff( |
| __isl_take isl_union_map *umap, |
| __isl_take isl_multi_union_pw_aff *mupa); |
| __isl_give isl_union_map * |
| isl_union_map_lex_lt_at_multi_union_pw_aff( |
| __isl_take isl_union_map *umap, |
| __isl_take isl_multi_union_pw_aff *mupa); |
| __isl_give isl_union_map * |
| isl_union_map_lex_gt_at_multi_union_pw_aff( |
| __isl_take isl_union_map *umap, |
| __isl_take isl_multi_union_pw_aff *mupa); |
| |
| These functions select the subset of elements in the union map |
| that have an equal or lexicographically smaller function value. |
| |
| =item * Cartesian Product |
| |
| #include <isl/space.h> |
| __isl_give isl_space *isl_space_product( |
| __isl_take isl_space *space1, |
| __isl_take isl_space *space2); |
| __isl_give isl_space *isl_space_domain_product( |
| __isl_take isl_space *space1, |
| __isl_take isl_space *space2); |
| __isl_give isl_space *isl_space_range_product( |
| __isl_take isl_space *space1, |
| __isl_take isl_space *space2); |
| |
| The functions |
| C<isl_space_product>, C<isl_space_domain_product> |
| and C<isl_space_range_product> take pairs or relation spaces and |
| produce a single relations space, where either the domain, the range |
| or both domain and range are wrapped spaces of relations between |
| the domains and/or ranges of the input spaces. |
| If the product is only constructed over the domain or the range |
| then the ranges or the domains of the inputs should be the same. |
| The function C<isl_space_product> also accepts a pair of set spaces, |
| in which case it returns a wrapped space of a relation between the |
| two input spaces. |
| |
| #include <isl/set.h> |
| __isl_give isl_set *isl_set_product( |
| __isl_take isl_set *set1, |
| __isl_take isl_set *set2); |
| |
| #include <isl/map.h> |
| __isl_give isl_basic_map *isl_basic_map_domain_product( |
| __isl_take isl_basic_map *bmap1, |
| __isl_take isl_basic_map *bmap2); |
| __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_map *isl_map_product( |
| __isl_take isl_map *map1, |
| __isl_take isl_map *map2); |
| |
| #include <isl/union_set.h> |
| __isl_give isl_union_set *isl_union_set_product( |
| __isl_take isl_union_set *uset1, |
| __isl_take isl_union_set *uset2); |
| |
| #include <isl/union_map.h> |
| __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_give isl_union_map *isl_union_map_product( |
| __isl_take isl_union_map *umap1, |
| __isl_take isl_union_map *umap2); |
| |
| #include <isl/val.h> |
| __isl_give isl_multi_val *isl_multi_val_range_product( |
| __isl_take isl_multi_val *mv1, |
| __isl_take isl_multi_val *mv2); |
| __isl_give isl_multi_val *isl_multi_val_product( |
| __isl_take isl_multi_val *mv1, |
| __isl_take isl_multi_val *mv2); |
| |
| #include <isl/aff.h> |
| __isl_give isl_multi_aff *isl_multi_aff_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_multi_pw_aff * |
| isl_multi_pw_aff_range_product( |
| __isl_take isl_multi_pw_aff *mpa1, |
| __isl_take isl_multi_pw_aff *mpa2); |
| __isl_give isl_multi_pw_aff *isl_multi_pw_aff_product( |
| __isl_take isl_multi_pw_aff *mpa1, |
| __isl_take isl_multi_pw_aff *mpa2); |
| __isl_give isl_pw_multi_aff * |
| isl_pw_multi_aff_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_multi_union_pw_aff * |
| isl_multi_union_pw_aff_range_product( |
| __isl_take isl_multi_union_pw_aff *mupa1, |
| __isl_take isl_multi_union_pw_aff *mupa2); |
| |
| The above functions compute the cross product of the given |
| sets, relations or functions. The domains and ranges of the results |
| are wrapped maps between domains and ranges of the inputs. |
| To obtain a ``flat'' product, use the following functions |
| instead. |
| |
| #include <isl/set.h> |
| __isl_give isl_basic_set *isl_basic_set_flat_product( |
| __isl_take isl_basic_set *bset1, |
| __isl_take isl_basic_set *bset2); |
| __isl_give isl_set *isl_set_flat_product( |
| __isl_take isl_set *set1, |
| __isl_take isl_set *set2); |
| |
| #include <isl/map.h> |
| __isl_give isl_basic_map *isl_basic_map_flat_range_product( |
| __isl_take isl_basic_map *bmap1, |
| __isl_take isl_basic_map *bmap2); |
| __isl_give isl_map *isl_map_flat_domain_product( |
| __isl_take isl_map *map1, |
| __isl_take isl_map *map2); |
| __isl_give isl_map *isl_map_flat_range_product( |
| __isl_take isl_map *map1, |
| __isl_take isl_map *map2); |
| __isl_give isl_basic_map *isl_basic_map_flat_product( |
| __isl_take isl_basic_map *bmap1, |
| __isl_take isl_basic_map *bmap2); |
| __isl_give isl_map *isl_map_flat_product( |
| __isl_take isl_map *map1, |
| __isl_take isl_map *map2); |
| |
| #include <isl/union_map.h> |
| __isl_give isl_union_map * |
| isl_union_map_flat_domain_product( |
| __isl_take isl_union_map *umap1, |
| __isl_take isl_union_map *umap2); |
| __isl_give isl_union_map * |
| isl_union_map_flat_range_product( |
| __isl_take isl_union_map *umap1, |
| __isl_take isl_union_map *umap2); |
| |
| #include <isl/val.h> |
| __isl_give isl_multi_val *isl_multi_val_flat_range_product( |
| __isl_take isl_multi_val *mv1, |
| __isl_take isl_multi_val *mv2); |
| |
| #include <isl/aff.h> |
| __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_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_multi_pw_aff * |
| isl_multi_pw_aff_flat_range_product( |
| __isl_take isl_multi_pw_aff *mpa1, |
| __isl_take isl_multi_pw_aff *mpa2); |
| __isl_give isl_union_pw_multi_aff * |
| isl_union_pw_multi_aff_flat_range_product( |
| __isl_take isl_union_pw_multi_aff *upma1, |
| __isl_take isl_union_pw_multi_aff *upma2); |
| __isl_give isl_multi_union_pw_aff * |
| isl_multi_union_pw_aff_flat_range_product( |
| __isl_take isl_multi_union_pw_aff *mupa1, |
| __isl_take isl_multi_union_pw_aff *mupa2); |
| |
| #include <isl/space.h> |
| __isl_give isl_space *isl_space_factor_domain( |
| __isl_take isl_space *space); |
| __isl_give isl_space *isl_space_factor_range( |
| __isl_take isl_space *space); |
| __isl_give isl_space *isl_space_domain_factor_domain( |
| __isl_take isl_space *space); |
| __isl_give isl_space *isl_space_domain_factor_range( |
| __isl_take isl_space *space); |
| __isl_give isl_space *isl_space_range_factor_domain( |
| __isl_take isl_space *space); |
| __isl_give isl_space *isl_space_range_factor_range( |
| __isl_take isl_space *space); |
| |
| The functions C<isl_space_range_factor_domain> and |
| C<isl_space_range_factor_range> extract the two arguments from |
| the result of a call to C<isl_space_range_product>. |
| |
| The arguments of a call to a product can be extracted |
| from the result using the following functions. |
| |
| #include <isl/map.h> |
| __isl_give isl_map *isl_map_factor_domain( |
| __isl_take isl_map *map); |
| __isl_give isl_map *isl_map_factor_range( |
| __isl_take isl_map *map); |
| __isl_give isl_map *isl_map_domain_factor_domain( |
| __isl_take isl_map *map); |
| __isl_give isl_map *isl_map_domain_factor_range( |
| __isl_take isl_map *map); |
| __isl_give isl_map *isl_map_range_factor_domain( |
| __isl_take isl_map *map); |
| __isl_give isl_map *isl_map_range_factor_range( |
| __isl_take isl_map *map); |
| |
| #include <isl/union_map.h> |
| __isl_give isl_union_map *isl_union_map_factor_domain( |
| __isl_take isl_union_map *umap); |
| __isl_give isl_union_map *isl_union_map_factor_range( |
| __isl_take isl_union_map *umap); |
| __isl_give isl_union_map * |
| isl_union_map_domain_factor_domain( |
| __isl_take isl_union_map *umap); |
| __isl_give isl_union_map * |
| isl_union_map_domain_factor_range( |
| __isl_take isl_union_map *umap); |
| __isl_give isl_union_map * |
| isl_union_map_range_factor_domain( |
| __isl_take isl_union_map *umap); |
| __isl_give isl_union_map * |
| isl_union_map_range_factor_range( |
| __isl_take isl_union_map *umap); |
| |
| #include <isl/val.h> |
| __isl_give isl_multi_val *isl_multi_val_factor_range( |
| __isl_take isl_multi_val *mv); |
| __isl_give isl_multi_val * |
| isl_multi_val_range_factor_domain( |
| __isl_take isl_multi_val *mv); |
| __isl_give isl_multi_val * |
| isl_multi_val_range_factor_range( |
| __isl_take isl_multi_val *mv); |
| |
| #include <isl/aff.h> |
| __isl_give isl_multi_aff *isl_multi_aff_factor_range( |
| __isl_take isl_multi_aff *ma); |
| __isl_give isl_multi_aff * |
| isl_multi_aff_range_factor_domain( |
| __isl_take isl_multi_aff *ma); |
| __isl_give isl_multi_aff * |
| isl_multi_aff_range_factor_range( |
| __isl_take isl_multi_aff *ma); |
| __isl_give isl_multi_pw_aff * |
| isl_multi_pw_aff_factor_range( |
| __isl_take isl_multi_pw_aff *mpa); |
| __isl_give isl_multi_pw_aff * |
| isl_multi_pw_aff_range_factor_domain( |
| __isl_take isl_multi_pw_aff *mpa); |
| __isl_give isl_multi_pw_aff * |
| isl_multi_pw_aff_range_factor_range( |
| __isl_take isl_multi_pw_aff *mpa); |
| __isl_give isl_multi_union_pw_aff * |
| isl_multi_union_pw_aff_factor_range( |
| __isl_take isl_multi_union_pw_aff *mupa); |
| __isl_give isl_multi_union_pw_aff * |
| isl_multi_union_pw_aff_range_factor_domain( |
| __isl_take isl_multi_union_pw_aff *mupa); |
| __isl_give isl_multi_union_pw_aff * |
| isl_multi_union_pw_aff_range_factor_range( |
| __isl_take isl_multi_union_pw_aff *mupa); |
| |
| The splice functions are a generalization of the flat product functions, |
| where the second argument may be inserted at any position inside |
| the first argument rather than being placed at the end. |
| The functions C<isl_multi_val_factor_range>, |
| C<isl_multi_aff_factor_range>, |
| C<isl_multi_pw_aff_factor_range> and |
| C<isl_multi_union_pw_aff_factor_range> |
| take functions that live in a set space. |
| |
| #include <isl/val.h> |
| __isl_give isl_multi_val *isl_multi_val_range_splice( |
| __isl_take isl_multi_val *mv1, unsigned pos, |
| __isl_take isl_multi_val *mv2); |
| |
| #include <isl/aff.h> |
| __isl_give isl_multi_aff *isl_multi_aff_range_splice( |
| __isl_take isl_multi_aff *ma1, unsigned pos, |
| __isl_take isl_multi_aff *ma2); |
| __isl_give isl_multi_aff *isl_multi_aff_splice( |
| __isl_take isl_multi_aff *ma1, |
| unsigned in_pos, unsigned out_pos, |
| __isl_take isl_multi_aff *ma2); |
| __isl_give isl_multi_pw_aff * |
| isl_multi_pw_aff_range_splice( |
| __isl_take isl_multi_pw_aff *mpa1, unsigned pos, |
| __isl_take isl_multi_pw_aff *mpa2); |
| __isl_give isl_multi_pw_aff *isl_multi_pw_aff_splice( |
| __isl_take isl_multi_pw_aff *mpa1, |
| unsigned in_pos, unsigned out_pos, |
| __isl_take isl_multi_pw_aff *mpa2); |
| __isl_give isl_multi_union_pw_aff * |
| isl_multi_union_pw_aff_range_splice( |
| __isl_take isl_multi_union_pw_aff *mupa1, |
| unsigned pos, |
| __isl_take isl_multi_union_pw_aff *mupa2); |
| |
| =item * Simplification |
| |
| When applied to a set or relation, |
| the gist operation returns a set or relation that has the |
| same intersection with the context as the input set or relation. |
| Any implicit equality in the intersection is made explicit in the result, |
| while all inequalities that are redundant with respect to the intersection |
| are removed. |
| In case of union sets and relations, the gist operation is performed |
| per space. |
| |
| When applied to a function, |
| the gist operation applies the set gist operation to each of |
| the cells in the domain of the input piecewise expression. |
| The context is also exploited |
| to simplify the expression associated to each cell. |
| |
| #include <isl/set.h> |
| __isl_give isl_basic_set *isl_basic_set_gist( |
| __isl_take isl_basic_set *bset, |
| __isl_take isl_basic_set *context); |
| __isl_give isl_set *isl_set_gist(__isl_take isl_set *set, |
| __isl_take isl_set *context); |
| __isl_give isl_set *isl_set_gist_params( |
| __isl_take isl_set *set, |
| __isl_take isl_set *context); |
| |
| #include <isl/map.h> |
| __isl_give isl_basic_map *isl_basic_map_gist( |
| __isl_take isl_basic_map *bmap, |
| __isl_take isl_basic_map *context); |
| __isl_give isl_basic_map *isl_basic_map_gist_domain( |
| __isl_take isl_basic_map *bmap, |
| __isl_take isl_basic_set *context); |
| __isl_give isl_map *isl_map_gist(__isl_take isl_map *map, |
| __isl_take isl_map *context); |
| __isl_give isl_map *isl_map_gist_params( |
| __isl_take isl_map *map, |
| __isl_take isl_set *context); |
| __isl_give isl_map *isl_map_gist_domain( |
| __isl_take isl_map *map, |
| __isl_take isl_set *context); |
| __isl_give isl_map *isl_map_gist_range( |
| __isl_take isl_map *map, |
| __isl_take isl_set *context); |
| |
| #include <isl/union_set.h> |
| __isl_give isl_union_set *isl_union_set_gist( |
| __isl_take isl_union_set *uset, |
| __isl_take isl_union_set *context); |
| __isl_give isl_union_set *isl_union_set_gist_params( |
| __isl_take isl_union_set *uset, |
| __isl_take isl_set *set); |
| |
| #include <isl/union_map.h> |
| __isl_give isl_union_map *isl_union_map_gist( |
| __isl_take isl_union_map *umap, |
| __isl_take isl_union_map *context); |
| __isl_give isl_union_map *isl_union_map_gist_params( |
| __isl_take isl_union_map *umap, |
| __isl_take isl_set *set); |
| __isl_give isl_union_map *isl_union_map_gist_domain( |
| __isl_take isl_union_map *umap, |
| __isl_take isl_union_set *uset); |
| __isl_give isl_union_map *isl_union_map_gist_range( |
| __isl_take isl_union_map *umap, |
| __isl_take isl_union_set *uset); |
| |
| #include <isl/aff.h> |
| __isl_give isl_aff *isl_aff_gist_params( |
| __isl_take isl_aff *aff, |
| __isl_take isl_set *context); |
| __isl_give isl_aff *isl_aff_gist(__isl_take isl_aff *aff, |
| __isl_take isl_set *context); |
| __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_gist( |
| __isl_take isl_multi_aff *maff, |
| __isl_take isl_set *context); |
| __isl_give isl_pw_aff *isl_pw_aff_gist_params( |
| __isl_take isl_pw_aff *pwaff, |
| __isl_take isl_set *context); |
| __isl_give isl_pw_aff *isl_pw_aff_gist( |
| __isl_take isl_pw_aff *pwaff, |
| __isl_take isl_set *context); |
| __isl_give isl_pw_multi_aff *isl_pw_multi_aff_gist_params( |
| __isl_take isl_pw_multi_aff *pma, |
| __isl_take isl_set *set); |
| __isl_give isl_pw_multi_aff *isl_pw_multi_aff_gist( |
| __isl_take isl_pw_multi_aff *pma, |
| __isl_take isl_set *set); |
| __isl_give isl_multi_pw_aff *isl_multi_pw_aff_gist_params( |
| __isl_take isl_multi_pw_aff *mpa, |
| __isl_take isl_set *set); |
| __isl_give isl_multi_pw_aff *isl_multi_pw_aff_gist( |
| __isl_take isl_multi_pw_aff *mpa, |
| __isl_take isl_set *set); |
| __isl_give isl_union_pw_aff *isl_union_pw_aff_gist( |
| __isl_take isl_union_pw_aff *upa, |
| __isl_take isl_union_set *context); |
| __isl_give isl_union_pw_aff *isl_union_pw_aff_gist_params( |
| __isl_take isl_union_pw_aff *upa, |
| __isl_take isl_set *context); |
| __isl_give isl_union_pw_multi_aff * |
| isl_union_pw_multi_aff_gist_params( |
| __isl_take isl_union_pw_multi_aff *upma, |
| __isl_take isl_set *context); |
| __isl_give isl_union_pw_multi_aff * |
| isl_union_pw_multi_aff_gist( |
| __isl_take isl_union_pw_multi_aff *upma, |
| __isl_take isl_union_set *context); |
| __isl_give isl_multi_union_pw_aff * |
| isl_multi_union_pw_aff_gist_params( |
| __isl_take isl_multi_union_pw_aff *aff, |
| __isl_take isl_set *context); |
| __isl_give isl_multi_union_pw_aff * |
| isl_multi_union_pw_aff_gist( |
| __isl_take isl_multi_union_pw_aff *aff, |
| __isl_take isl_union_set *context); |
| |
| #include <isl/polynomial.h> |
| __isl_give isl_qpolynomial *isl_qpolynomial_gist_params( |
| __isl_take isl_qpolynomial *qp, |
| __isl_take isl_set *context); |
| __isl_give isl_qpolynomial *isl_qpolynomial_gist( |
| __isl_take isl_qpolynomial *qp, |
| __isl_take isl_set *context); |
| __isl_give isl_qpolynomial_fold * |
| isl_qpolynomial_fold_gist_params( |
| __isl_take isl_qpolynomial_fold *fold, |
| __isl_take isl_set *context); |
| __isl_give isl_qpolynomial_fold *isl_qpolynomial_fold_gist( |
| __isl_take isl_qpolynomial_fold *fold, |
| __isl_take isl_set *context); |
| __isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_gist_params( |
| __isl_take isl_pw_qpolynomial *pwqp, |
| __isl_take isl_set *context); |
| __isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_gist( |
| __isl_take isl_pw_qpolynomial *pwqp, |
| __isl_take isl_set *context); |
| __isl_give isl_pw_qpolynomial_fold * |
| isl_pw_qpolynomial_fold_gist( |
| __isl_take isl_pw_qpolynomial_fold *pwf, |
| __isl_take isl_set *context); |
| __isl_give isl_pw_qpolynomial_fold * |
| isl_pw_qpolynomial_fold_gist_params( |
| __isl_take isl_pw_qpolynomial_fold *pwf, |
| __isl_take isl_set *context); |
| __isl_give isl_union_pw_qpolynomial * |
| isl_union_pw_qpolynomial_gist_params( |
| __isl_take isl_union_pw_qpolynomial *upwqp, |
| __isl_take isl_set *context); |
| __isl_give isl_union_pw_qpolynomial *isl_union_pw_qpolynomial_gist( |
| __isl_take isl_union_pw_qpolynomial *upwqp, |
| __isl_take isl_union_set *context); |
| __isl_give isl_union_pw_qpolynomial_fold * |
| isl_union_pw_qpolynomial_fold_gist( |
| __isl_take isl_union_pw_qpolynomial_fold *upwf, |
| __isl_take isl_union_set *context); |
| __isl_give isl_union_pw_qpolynomial_fold * |
| isl_union_pw_qpolynomial_fold_gist_params( |
| __isl_take isl_union_pw_qpolynomial_fold *upwf, |
| __isl_take isl_set *context); |
| |
| =item * Binary Arithmetic Operations |
| |
| #include <isl/set.h> |
| __isl_give isl_set *isl_set_sum( |
| __isl_take isl_set *set1, |
| __isl_take isl_set *set2); |
| #include <isl/map.h> |
| __isl_give isl_map *isl_map_sum( |
| __isl_take isl_map *map1, |
| __isl_take isl_map *map2); |
| |
| C<isl_set_sum> computes the Minkowski sum of its two arguments, |
| i.e., the set containing the sums of pairs of elements from |
| C<set1> and C<set2>. |
| The domain of the result of C<isl_map_sum> is the intersection |
| of the domains of its two arguments. The corresponding range |
| elements are the sums of the corresponding range elements |
| in the two arguments. |
| |
| #include <isl/val.h> |
| __isl_give isl_multi_val *isl_multi_val_add( |
| __isl_take isl_multi_val *mv1, |
| __isl_take isl_multi_val *mv2); |
| __isl_give isl_multi_val *isl_multi_val_sub( |
| __isl_take isl_multi_val *mv1, |
| __isl_take isl_multi_val *mv2); |
| |
| #include <isl/aff.h> |
| __isl_give isl_aff *isl_aff_add( |
| __isl_take isl_aff *aff1, |
| __isl_take isl_aff *aff2); |
| __isl_give isl_multi_aff *isl_multi_aff_add( |
| __isl_take isl_multi_aff *maff1, |
| __isl_take isl_multi_aff *maff2); |
| __isl_give isl_pw_aff *isl_pw_aff_add( |
| __isl_take isl_pw_aff *pwaff1, |
| __isl_take isl_pw_aff *pwaff2); |
| __isl_give isl_multi_pw_aff *isl_multi_pw_aff_add( |
| __isl_take isl_multi_pw_aff *mpa1, |
| __isl_take isl_multi_pw_aff *mpa2); |
| __isl_give isl_pw_multi_aff *isl_pw_multi_aff_add( |
| __isl_take isl_pw_multi_aff *pma1, |
| __isl_take isl_pw_multi_aff *pma2); |
| __isl_give isl_union_pw_aff *isl_union_pw_aff_add( |
| __isl_take isl_union_pw_aff *upa1, |
| __isl_take isl_union_pw_aff *upa2); |
| __isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_add( |
| __isl_take isl_union_pw_multi_aff *upma1, |
| __isl_take isl_union_pw_multi_aff *upma2); |
| __isl_give isl_multi_union_pw_aff * |
| isl_multi_union_pw_aff_add( |
| __isl_take isl_multi_union_pw_aff *mupa1, |
| __isl_take isl_multi_union_pw_aff *mupa2); |
| __isl_give isl_pw_aff *isl_pw_aff_min( |
| __isl_take isl_pw_aff *pwaff1, |
| __isl_take isl_pw_aff *pwaff2); |
| __isl_give isl_pw_aff *isl_pw_aff_max( |
| __isl_take isl_pw_aff *pwaff1, |
| __isl_take isl_pw_aff *pwaff2); |
| __isl_give isl_aff *isl_aff_sub( |
| __isl_take isl_aff *aff1, |
| __isl_take isl_aff *aff2); |
| __isl_give isl_multi_aff *isl_multi_aff_sub( |
| __isl_take isl_multi_aff *ma1, |
| __isl_take isl_multi_aff *ma2); |
| __isl_give isl_pw_aff *isl_pw_aff_sub( |
| __isl_take isl_pw_aff *pwaff1, |
| __isl_take isl_pw_aff *pwaff2); |
| __isl_give isl_multi_pw_aff *isl_multi_pw_aff_sub( |
| __isl_take isl_multi_pw_aff *mpa1, |
| __isl_take isl_multi_pw_aff *mpa2); |
| __isl_give isl_pw_multi_aff *isl_pw_multi_aff_sub( |
| __isl_take isl_pw_multi_aff *pma1, |
| __isl_take isl_pw_multi_aff *pma2); |
| __isl_give isl_union_pw_aff *isl_union_pw_aff_sub( |
| __isl_take isl_union_pw_aff *upa1, |
| __isl_take isl_union_pw_aff *upa2); |
| __isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_sub( |
| __isl_take isl_union_pw_multi_aff *upma1, |
| __isl_take isl_union_pw_multi_aff *upma2); |
| __isl_give isl_multi_union_pw_aff * |
| isl_multi_union_pw_aff_sub( |
| __isl_take isl_multi_union_pw_aff *mupa1, |
| __isl_take isl_multi_union_pw_aff *mupa2); |
| |
| C<isl_aff_sub> subtracts the second argument from the first. |
| |
| #include <isl/polynomial.h> |
| __isl_give isl_qpolynomial *isl_qpolynomial_add( |
| __isl_take isl_qpolynomial *qp1, |
| __isl_take isl_qpolynomial *qp2); |
| __isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_add( |
| __isl_take isl_pw_qpolynomial *pwqp1, |
| __isl_take isl_pw_qpolynomial *pwqp2); |
| __isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_add_disjoint( |
| __isl_take isl_pw_qpolynomial *pwqp1, |
| __isl_take isl_pw_qpolynomial *pwqp2); |
| __isl_give isl_pw_qpolynomial_fold *isl_pw_qpolynomial_fold_add( |
| __isl_take isl_pw_qpolynomial_fold *pwf1, |
| __isl_take isl_pw_qpolynomial_fold *pwf2); |
| __isl_give isl_union_pw_qpolynomial *isl_union_pw_qpolynomial_add( |
| __isl_take isl_union_pw_qpolynomial *upwqp1, |
| __isl_take isl_union_pw_qpolynomial *upwqp2); |
| __isl_give isl_qpolynomial *isl_qpolynomial_sub( |
| __isl_take isl_qpolynomial *qp1, |
| __isl_take isl_qpolynomial *qp2); |
| __isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_sub( |
| __isl_take isl_pw_qpolynomial *pwqp1, |
| __isl_take isl_pw_qpolynomial *pwqp2); |
| __isl_give isl_union_pw_qpolynomial *isl_union_pw_qpolynomial_sub( |
| __isl_take isl_union_pw_qpolynomial *upwqp1, |
| __isl_take isl_union_pw_qpolynomial *upwqp2); |
| __isl_give isl_pw_qpolynomial_fold *isl_pw_qpolynomial_fold_fold( |
| __isl_take isl_pw_qpolynomial_fold *pwf1, |
| __isl_take isl_pw_qpolynomial_fold *pwf2); |
| __isl_give isl_union_pw_qpolynomial_fold * |
| isl_union_pw_qpolynomial_fold_fold( |
| __isl_take isl_union_pw_qpolynomial_fold *upwf1, |
| __isl_take isl_union_pw_qpolynomial_fold *upwf2); |
| |
| #include <isl/aff.h> |
| __isl_give isl_pw_aff *isl_pw_aff_union_add( |
| __isl_take isl_pw_aff *pwaff1, |
| __isl_take isl_pw_aff *pwaff2); |
| __isl_give isl_pw_multi_aff *isl_pw_multi_aff_union_add( |
| __isl_take isl_pw_multi_aff *pma1, |
| __isl_take isl_pw_multi_aff *pma2); |
| __isl_give isl_union_pw_aff *isl_union_pw_aff_union_add( |
| __isl_take isl_union_pw_aff *upa1, |
| __isl_take isl_union_pw_aff *upa2); |
| __isl_give isl_union_pw_multi_aff * |
| isl_union_pw_multi_aff_union_add( |
| __isl_take isl_union_pw_multi_aff *upma1, |
| __isl_take isl_union_pw_multi_aff *upma2); |
| __isl_give isl_multi_union_pw_aff * |
| isl_multi_union_pw_aff_union_add( |
| __isl_take isl_multi_union_pw_aff *mupa1, |
| __isl_take isl_multi_union_pw_aff *mupa2); |
| __isl_give isl_pw_aff *isl_pw_aff_union_min( |
| __isl_take isl_pw_aff *pwaff1, |
| __isl_take isl_pw_aff *pwaff2); |
| __isl_give isl_pw_aff *isl_pw_aff_union_max( |
| __isl_take isl_pw_aff *pwaff1, |
| __isl_take isl_pw_aff *pwaff2); |
| |
| The function C<isl_pw_aff_union_max> computes a piecewise quasi-affine |
| expression with a domain that is the union of those of C<pwaff1> and |
| C<pwaff2> and such that on each cell, the quasi-affine expression is |
| the maximum of those of C<pwaff1> and C<pwaff2>. If only one of |
| C<pwaff1> or C<pwaff2> is defined on a given cell, then the |
| associated expression is the defined one. |
| This in contrast to the C<isl_pw_aff_max> function, which is |
| only defined on the shared definition domain of the arguments. |
| |
| #include <isl/val.h> |
| __isl_give isl_multi_val *isl_multi_val_add_val( |
| __isl_take isl_multi_val *mv, |
| __isl_take isl_val *v); |
| __isl_give isl_multi_val *isl_multi_val_mod_val( |
| __isl_take isl_multi_val *mv, |
| __isl_take isl_val *v); |
| __isl_give isl_multi_val *isl_multi_val_scale_val( |
| __isl_take isl_multi_val *mv, |
| __isl_take isl_val *v); |
| __isl_give isl_multi_val *isl_multi_val_scale_down_val( |
| __isl_take isl_multi_val *mv, |
| __isl_take isl_val *v); |
| |
| #include <isl/aff.h> |
| __isl_give isl_aff *isl_aff_mod_val(__isl_take isl_aff *aff, |
| __isl_take isl_val *mod); |
| __isl_give isl_pw_aff *isl_pw_aff_mod_val( |
| __isl_take isl_pw_aff *pa, |
| __isl_take isl_val *mod); |
| __isl_give isl_union_pw_aff *isl_union_pw_aff_mod_val( |
| __isl_take isl_union_pw_aff *upa, |
| __isl_take isl_val *f); |
| __isl_give isl_aff *isl_aff_scale_val(__isl_take isl_aff *aff, |
| __isl_take isl_val *v); |
| __isl_give isl_multi_aff *isl_multi_aff_scale_val( |
| __isl_take isl_multi_aff *ma, |
| __isl_take isl_val *v); |
| __isl_give isl_pw_aff *isl_pw_aff_scale_val( |
| __isl_take isl_pw_aff *pa, __isl_take isl_val *v); |
| __isl_give isl_multi_pw_aff *isl_multi_pw_aff_scale_val( |
| __isl_take isl_multi_pw_aff *mpa, |
| __isl_take isl_val *v); |
| __isl_give isl_pw_multi_aff *isl_pw_multi_aff_scale_val( |
| __isl_take isl_pw_multi_aff *pma, |
| __isl_take isl_val *v); |
| __isl_give isl_union_pw_multi_aff * |
| __isl_give isl_union_pw_aff *isl_union_pw_aff_scale_val( |
| __isl_take isl_union_pw_aff *upa, |
| __isl_take isl_val *f); |
| isl_union_pw_multi_aff_scale_val( |
| __isl_take isl_union_pw_multi_aff *upma, |
| __isl_take isl_val *val); |
| __isl_give isl_multi_union_pw_aff * |
| isl_multi_union_pw_aff_scale_val( |
| __isl_take isl_multi_union_pw_aff *mupa, |
| __isl_take isl_val *v); |
| __isl_give isl_aff *isl_aff_scale_down_ui( |
| __isl_take isl_aff *aff, unsigned f); |
| __isl_give isl_aff *isl_aff_scale_down_val( |
| __isl_take isl_aff *aff, __isl_take isl_val *v); |
| __isl_give isl_multi_aff *isl_multi_aff_scale_down_val( |
| __isl_take isl_multi_aff *ma, |
| __isl_take isl_val *v); |
| __isl_give isl_pw_aff *isl_pw_aff_scale_down_val( |
| __isl_take isl_pw_aff *pa, |
| __isl_take isl_val *f); |
| __isl_give isl_multi_pw_aff *isl_multi_pw_aff_scale_down_val( |
| __isl_take isl_multi_pw_aff *mpa, |
| __isl_take isl_val *v); |
| __isl_give isl_pw_multi_aff *isl_pw_multi_aff_scale_down_val( |
| __isl_take isl_pw_multi_aff *pma, |
| __isl_take isl_val *v); |
| __isl_give isl_union_pw_aff *isl_union_pw_aff_scale_down_val( |
| __isl_take isl_union_pw_aff *upa, |
| __isl_take isl_val *v); |
| __isl_give isl_union_pw_multi_aff * |
| isl_union_pw_multi_aff_scale_down_val( |
| __isl_take isl_union_pw_multi_aff *upma, |
| __isl_take isl_val *val); |
| __isl_give isl_multi_union_pw_aff * |
| isl_multi_union_pw_aff_scale_down_val( |
| __isl_take isl_multi_union_pw_aff *mupa, |
| __isl_take isl_val *v); |
| |
| #include <isl/polynomial.h> |
| __isl_give isl_qpolynomial *isl_qpolynomial_scale_val( |
| __isl_take isl_qpolynomial *qp, |
| __isl_take isl_val *v); |
| __isl_give isl_qpolynomial_fold * |
| isl_qpolynomial_fold_scale_val( |
| __isl_take isl_qpolynomial_fold *fold, |
| __isl_take isl_val *v); |
| __isl_give isl_pw_qpolynomial * |
| isl_pw_qpolynomial_scale_val( |
| __isl_take isl_pw_qpolynomial *pwqp, |
| __isl_take isl_val *v); |
| __isl_give isl_pw_qpolynomial_fold * |
| isl_pw_qpolynomial_fold_scale_val( |
| __isl_take isl_pw_qpolynomial_fold *pwf, |
| __isl_take isl_val *v); |
| __isl_give isl_union_pw_qpolynomial * |
| isl_union_pw_qpolynomial_scale_val( |
| __isl_take isl_union_pw_qpolynomial *upwqp, |
| __isl_take isl_val *v); |
| __isl_give isl_union_pw_qpolynomial_fold * |
| isl_union_pw_qpolynomial_fold_scale_val( |
| __isl_take isl_union_pw_qpolynomial_fold *upwf, |
| __isl_take isl_val *v); |
| __isl_give isl_qpolynomial * |
| isl_qpolynomial_scale_down_val( |
| __isl_take isl_qpolynomial *qp, |
| __isl_take isl_val *v); |
| __isl_give isl_qpolynomial_fold * |
| isl_qpolynomial_fold_scale_down_val( |
| __isl_take isl_qpolynomial_fold *fold, |
| __isl_take isl_val *v); |
| __isl_give isl_pw_qpolynomial * |
| isl_pw_qpolynomial_scale_down_val( |
| __isl_take isl_pw_qpolynomial *pwqp, |
| __isl_take isl_val *v); |
| __isl_give isl_pw_qpolynomial_fold * |
| isl_pw_qpolynomial_fold_scale_down_val( |
| __isl_take isl_pw_qpolynomial_fold *pwf, |
| __isl_take isl_val *v); |
| __isl_give isl_union_pw_qpolynomial * |
| isl_union_pw_qpolynomial_scale_down_val( |
| __isl_take isl_union_pw_qpolynomial *upwqp, |
| __isl_take isl_val *v); |
| __isl_give isl_union_pw_qpolynomial_fold * |
| isl_union_pw_qpolynomial_fold_scale_down_val( |
| __isl_take isl_union_pw_qpolynomial_fold *upwf, |
| __isl_take isl_val *v); |
| |
| #include <isl/val.h> |
| __isl_give isl_multi_val *isl_multi_val_mod_multi_val( |
| __isl_take isl_multi_val *mv1, |
| __isl_take isl_multi_val *mv2); |
| __isl_give isl_multi_val *isl_multi_val_scale_multi_val( |
| __isl_take isl_multi_val *mv1, |
| __isl_take isl_multi_val *mv2); |
| __isl_give isl_multi_val * |
| isl_multi_val_scale_down_multi_val( |
| __isl_take isl_multi_val *mv1, |
| __isl_take isl_multi_val *mv2); |
| |
| #include <isl/aff.h> |
| __isl_give isl_multi_aff *isl_multi_aff_mod_multi_val( |
| __isl_take isl_multi_aff *ma, |
| __isl_take isl_multi_val *mv); |
| __isl_give isl_multi_union_pw_aff * |
| isl_multi_union_pw_aff_mod_multi_val( |
| __isl_take isl_multi_union_pw_aff *upma, |
| __isl_take isl_multi_val *mv); |
| __isl_give isl_multi_pw_aff * |
| isl_multi_pw_aff_mod_multi_val( |
| __isl_take isl_multi_pw_aff *mpa, |
| __isl_take isl_multi_val *mv); |
| __isl_give isl_multi_aff *isl_multi_aff_scale_multi_val( |
| __isl_take isl_multi_aff *ma, |
| __isl_take isl_multi_val *mv); |
| __isl_give isl_pw_multi_aff * |
| isl_pw_multi_aff_scale_multi_val( |
| __isl_take isl_pw_multi_aff *pma, |
| __isl_take isl_multi_val *mv); |
| __isl_give isl_multi_pw_aff * |
| isl_multi_pw_aff_scale_multi_val( |
| __isl_take isl_multi_pw_aff *mpa, |
| __isl_take isl_multi_val *mv); |
| __isl_give isl_multi_union_pw_aff * |
| isl_multi_union_pw_aff_scale_multi_val( |
| __isl_take isl_multi_union_pw_aff *mupa, |
| __isl_take isl_multi_val *mv); |
| __isl_give isl_union_pw_multi_aff * |
| isl_union_pw_multi_aff_scale_multi_val( |
| __isl_take isl_union_pw_multi_aff *upma, |
| __isl_take isl_multi_val *mv); |
| __isl_give isl_multi_aff * |
| isl_multi_aff_scale_down_multi_val( |
| __isl_take isl_multi_aff *ma, |
| __isl_take isl_multi_val *mv); |
| __isl_give isl_multi_pw_aff * |
| isl_multi_pw_aff_scale_down_multi_val( |
| __isl_take isl_multi_pw_aff *mpa, |
| __isl_take isl_multi_val *mv); |
| __isl_give isl_multi_union_pw_aff * |
| isl_multi_union_pw_aff_scale_down_multi_val( |
| __isl_take isl_multi_union_pw_aff *mupa, |
| __isl_take isl_multi_val *mv); |
| |
| C<isl_multi_aff_scale_multi_val> scales the elements of C<ma> |
| by the corresponding elements of C<mv>. |
| |
| #include <isl/aff.h> |
| __isl_give isl_aff *isl_aff_mul( |
| __isl_take isl_aff *aff1, |
| __isl_take isl_aff *aff2); |
| __isl_give isl_aff *isl_aff_div( |
| __isl_take isl_aff *aff1, |
| __isl_take isl_aff *aff2); |
| __isl_give isl_pw_aff *isl_pw_aff_mul( |
| __isl_take isl_pw_aff *pwaff1, |
| __isl_take isl_pw_aff *pwaff2); |
| __isl_give isl_pw_aff *isl_pw_aff_div( |
| __isl_take isl_pw_aff *pa1, |
| __isl_take isl_pw_aff *pa2); |
| __isl_give isl_pw_aff *isl_pw_aff_tdiv_q( |
| __isl_take isl_pw_aff *pa1, |
| __isl_take isl_pw_aff *pa2); |
| __isl_give isl_pw_aff *isl_pw_aff_tdiv_r( |
| __isl_take isl_pw_aff *pa1, |
| __isl_take isl_pw_aff *pa2); |
| |
| When multiplying two affine expressions, at least one of the two needs |
| to be a constant. Similarly, when dividing an affine expression by another, |
| the second expression needs to be a constant. |
| C<isl_pw_aff_tdiv_q> computes the quotient of an integer division with |
| rounding towards zero. C<isl_pw_aff_tdiv_r> computes the corresponding |
| remainder. |
| |
| #include <isl/polynomial.h> |
| __isl_give isl_qpolynomial *isl_qpolynomial_mul( |
| __isl_take isl_qpolynomial *qp1, |
| __isl_take isl_qpolynomial *qp2); |
| __isl_give isl_pw_qpolynomial *isl_pw_qpolynomial_mul( |
| __isl_take isl_pw_qpolynomial *pwqp1, |
| __isl_take isl_pw_qpolynomial *pwqp2); |
| __isl_give isl_union_pw_qpolynomial *isl_union_pw_qpolynomial_mul( |
| __isl_take isl_union_pw_qpolynomial *upwqp1, |
| __isl_take isl_union_pw_qpolynomial *upwqp2); |
| |
| =back |
| |
| =head3 Lexicographic Optimization |
| |
| Given a (basic) set C<set> (or C<bset>) and a zero-dimensional domain C<dom>, |
| the following functions |
| compute a set that contains the lexicographic minimum or maximum |
| of the elements in C<set> (or C<bset>) for those values of the parameters |
| that satisfy C<dom>. |
| If C<empty> is not C<NULL>, then C<*empty> is assigned a set |
| that contains the parameter values in C<dom> for which C<set> (or C<bset>) |
| has no elements. |
| In other words, the union of the parameter values |
| for which the result is non-empty and of C<*empty> |
| is equal to C<dom>. |
| |
| #include <isl/set.h> |
| __isl_give isl_set *isl_basic_set_partial_lexmin( |
| __isl_take isl_basic_set *bset, |
| __isl_take isl_basic_set *dom, |
| __isl_give isl_set **empty); |
| __isl_give isl_set *isl_basic_set_partial_lexmax( |
| __isl_take isl_basic_set *bset, |
| __isl_take isl_basic_set *dom, |
| __isl_give isl_set **empty); |
| __isl_give isl_set *isl_set_partial_lexmin( |
| __isl_take isl_set *set, __isl_take isl_set *dom, |
| __isl_give isl_set **empty); |
| __isl_give isl_set *isl_set_partial_lexmax( |
| __isl_take isl_set *set, __isl_take isl_set *dom, |
| __isl_give isl_set **empty); |
| |
| Given a (basic) set C<set> (or C<bset>), the following functions simply |
| return a set containing the lexicographic minimum or maximum |
| of the elements in C<set> (or C<bset>). |
| In case of union sets, the optimum is computed per space. |
| |
| #include <isl/set.h> |
| __isl_give isl_set *isl_basic_set_lexmin( |
| __isl_take isl_basic_set *bset); |
| __isl_give isl_set *isl_basic_set_lexmax( |
| __isl_take isl_basic_set *bset); |
| __isl_give isl_set *isl_set_lexmin( |
| __isl_take isl_set *set); |
| __isl_give isl_set *isl_set_lexmax( |
| __isl_take isl_set *set); |
| __isl_give isl_union_set *isl_union_set_lexmin( |
| __isl_take isl_union_set *uset); |
| __isl_give isl_union_set *isl_union_set_lexmax( |
| __isl_take isl_union_set *uset); |
| |
| Given a (basic) relation C<map> (or C<bmap>) and a domain C<dom>, |
| the following functions |
| compute a relation that maps each element of C<dom> |
| to the single lexicographic minimum or maximum |
| of the elements that are associated to that same |
| element in C<map> (or C<bmap>). |
| If C<empty> is not C<NULL>, then C<*empty> is assigned a set |
| that contains the elements in C<dom> that do not map |
| to any elements in C<map> (or C<bmap>). |
| In other words, the union of the domain of the result and of C<*empty> |
| is equal to C<dom>. |
| |
| #include <isl/map.h> |
| __isl_give isl_map *isl_basic_map_partial_lexmax( |
| __isl_take isl_basic_map *bmap, |
| __isl_take isl_basic_set *dom, |
| __isl_give isl_set **empty); |
| __isl_give isl_map *isl_basic_map_partial_lexmin( |
| __isl_take isl_basic_map *bmap, |
| __isl_take isl_basic_set *dom, |
| __isl_give isl_set **empty); |
| __isl_give isl_map *isl_map_partial_lexmax( |
| __isl_take isl_map *map, __isl_take isl_set *dom, |
| __isl_give isl_set **empty); |
| __isl_give isl_map *isl_map_partial_lexmin( |
| __isl_take isl_map *map, __isl_take isl_set *dom, |
| __isl_give isl_set **empty); |
| |
| Given a (basic) map C<map> (or C<bmap>), the following functions simply |
| return a map mapping each element in the domain of |
| C<map> (or C<bmap>) to the lexicographic minimum or maximum |
| of all elements associated to that element. |
| In case of union relations, the optimum is computed per space. |
| |
| #include <isl/map.h> |
| __isl_give isl_map *isl_basic_map_lexmin( |
| __isl_take isl_basic_map *bmap); |
| __isl_give isl_map *isl_basic_map_lexmax( |
| __isl_take isl_basic_map *bmap); |
| __isl_give isl_map *isl_map_lexmin( |
| __isl_take isl_map *map); |
| __isl_give isl_map *isl_map_lexmax( |
| __isl_take isl_map *map); |
| __isl_give isl_union_map *isl_union_map_lexmin( |
| __isl_take isl_union_map *umap); |
| __isl_give isl_union_map *isl_union_map_lexmax( |
| __isl_take isl_union_map *umap); |
| |
| The following functions return their result in the form of |
| a piecewise multi-affine expression, |
| but are otherwise equivalent to the corresponding functions |
| returning a basic set or relation. |
| |
| #include <isl/set.h> |
| __isl_give isl_pw_multi_aff * |
| isl_basic_set_partial_lexmin_pw_multi_aff( |
| __isl_take isl_basic_set *bset, |
| __isl_take isl_basic_set *dom, |
| __isl_give isl_set **empty); |
| __isl_give isl_pw_multi_aff * |
| isl_basic_set_partial_lexmax_pw_multi_aff( |
| __isl_take isl_basic_set *bset, |
| __isl_take isl_basic_set *dom, |
| __isl_give isl_set **empty); |
| __isl_give isl_pw_multi_aff *isl_set_lexmin_pw_multi_aff( |
| __isl_take isl_set *set); |
| __isl_give isl_pw_multi_aff *isl_set_lexmax_pw_multi_aff( |
| __isl_take isl_set *set); |
| |
| #include <isl/map.h> |
| __isl_give isl_pw_multi_aff * |
| isl_basic_map_lexmin_pw_multi_aff( |
| __isl_take isl_basic_map *bmap); |
| __isl_give isl_pw_multi_aff * |
| isl_basic_map_partial_lexmin_pw_multi_aff( |
| __isl_take isl_basic_map *bmap, |
| __isl_take isl_basic_set *dom, |
| __isl_give isl_set **empty); |
| __isl_give isl_pw_multi_aff * |
| isl_basic_map_partial_lexmax_pw_multi_aff( |
| __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); |
| |
| The following functions return the lexicographic minimum or maximum |
| on the shared domain of the inputs and the single defined function |
| on those parts of the domain where only a single function is defined. |
| |
| #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); |
| |
| If the input to a lexicographic optimization problem has |
| multiple constraints with the same coefficients for the optimized |
| variables, then, by default, this symmetry is exploited by |
| replacing those constraints by a single constraint with |
| an abstract bound, which is in turn bounded by the corresponding terms |
| in the original constraints. |
| Without this optimization, the solver would typically consider |
| all possible orderings of those original bounds, resulting in a needless |
| decomposition of the domain. |
| However, the optimization can also result in slowdowns since |
| an extra parameter is introduced that may get used in additional |
| integer divisions. |
| The following option determines whether symmetry detection is applied |
| during lexicographic optimization. |
| |
| #include <isl/options.h> |
| isl_stat isl_options_set_pip_symmetry(isl_ctx *ctx, |
| int val); |
| int isl_options_get_pip_symmetry(isl_ctx *ctx); |
| |
| =begin latex |
| |
| See also \autoref{s:offline}. |
| |
| =end latex |
| |
| =head2 Ternary Operations |
| |
| #include <isl/aff.h> |
| __isl_give isl_pw_aff *isl_pw_aff_cond( |
| __isl_take isl_pw_aff *cond, |
| __isl_take isl_pw_aff *pwaff_true, |
| __isl_take isl_pw_aff *pwaff_false); |
| |
| The function C<isl_pw_aff_cond> performs a conditional operator |
| and returns an expression that is equal to C<pwaff_true> |
| for elements where C<cond> is non-zero and equal to C<pwaff_false> for elements |
| where C<cond> is zero. |
| |
| =head2 Lists |
| |
| Lists are defined over several element types, including |
| C<isl_val>, C<isl_id>, C<isl_aff>, C<isl_pw_aff>, C<isl_pw_multi_aff>, |
| C<isl_union_pw_aff>, |
| C<isl_union_pw_multi_aff>, |
| C<isl_pw_qpolynomial>, C<isl_pw_qpolynomial_fold>, |
| C<isl_constraint>, |
| C<isl_basic_set>, C<isl_set>, C<isl_basic_map>, C<isl_map>, C<isl_union_set>, |
| C<isl_union_map>, C<isl_ast_expr> and C<isl_ast_node>. |
| Here we take lists of C<isl_set>s as an example. |
| Lists can be created, copied, modified and freed using the following functions. |
| |
| #include <isl/set.h> |
| __isl_give isl_set_list *isl_set_list_from_set( |
| __isl_take isl_set *el); |
| __isl_give isl_set_list *isl_set_list_alloc( |
| isl_ctx *ctx, int n); |
| __isl_give isl_set_list *isl_set_list_copy( |
| __isl_keep isl_set_list *list); |
| __isl_give isl_set_list *isl_set_list_insert( |
| __isl_take isl_set_list *list, unsigned pos, |
| __isl_take isl_set *el); |
| __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_swap( |
| __isl_take isl_set_list *list, |
| unsigned pos1, unsigned pos2); |
| __isl_give isl_set_list *isl_set_list_reverse( |
| __isl_take isl_set_list *list); |
| __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_set_list *isl_set_list_map( |
| __isl_take isl_set_list *list, |
| __isl_give isl_set *(*fn)(__isl_take isl_set *el, |
| void *user), |
| void *user); |
| __isl_give isl_set_list *isl_set_list_sort( |
| __isl_take isl_set_list *list, |
| int (*cmp)(__isl_keep isl_set *a, |
| __isl_keep isl_set *b, void *user), |
| void *user); |
| __isl_null isl_set_list *isl_set_list_free( |
| __isl_take isl_set_list *list); |
| |
| C<isl_set_list_alloc> creates an empty list with an initial capacity |
| for C<n> elements. C<isl_set_list_insert> and C<isl_set_list_add> |
| add elements to a list, increasing its capacity as needed. |
| C<isl_set_list_from_set> creates a list with a single element. |
| C<isl_set_list_swap> swaps the elements at the specified locations. |
| C<isl_set_list_reverse> reverses the elements in the list. |
| |
| Lists can be inspected using the following functions. |
| |
| #include <isl/set.h> |
| int isl_set_list_size(__isl_keep isl_set_list *list); |
| int isl_set_list_n_set(__isl_keep isl_set_list *list); |
| __isl_give isl_set *isl_set_list_get_at( |
| __isl_keep isl_set_list *list, int index); |
| __isl_give isl_set *isl_set_list_get_set( |
| __isl_keep isl_set_list *list, int index); |
| isl_stat isl_set_list_foreach(__isl_keep isl_set_list *list, |
| isl_stat (*fn)(__isl_take isl_set *el, void *user), |
| void *user); |
| isl_stat isl_set_list_foreach_scc( |
| __isl_keep isl_set_list *list, |
| isl_bool (*follows)(__isl_keep isl_set *a, |
| __isl_keep isl_set *b, void *user), |
| void *follows_user, |
| isl_stat (*fn)(__isl_take isl_set *el, void *user), |
| void *fn_user); |
| |
| C<isl_set_list_n_set> is an alternative name for C<isl_set_list_size>. |
| Similarly, |
| C<isl_set_list_get_set> is an alternative name for C<isl_set_list_get_at>. |
| The function C<isl_set_list_foreach_scc> calls C<fn> on each of the |
| strongly connected components of the graph with as vertices the elements |
| of C<list> and a directed edge from vertex C<b> to vertex C<a> |
| iff C<follows(a, b)> returns C<isl_bool_true>. The callbacks C<follows> and |
| C<fn> should return C<isl_bool_error> or C<isl_stat_error> on error. |
| |
| Lists can be printed using |
| |
| #include <isl/set.h> |
| __isl_give isl_printer *isl_printer_print_set_list( |
| __isl_take isl_printer *p, |
| __isl_keep isl_set_list *list); |
| |
| =head2 Associative arrays |
| |
| Associative arrays map isl objects of a specific type to isl objects |
| of some (other) specific type. They are defined for several pairs |
| of types, including (C<isl_map>, C<isl_basic_set>), |
| (C<isl_id>, C<isl_ast_expr>), |
| (C<isl_id>, C<isl_id>) and |
| (C<isl_id>, C<isl_pw_aff>). |
| Here, we take associative arrays that map C<isl_id>s to C<isl_ast_expr>s |
| as an example. |
| |
| Associative arrays can be created, copied and freed using |
| the following functions. |
| |
| #include <isl/id_to_ast_expr.h> |
| __isl_give isl_id_to_ast_expr *isl_id_to_ast_expr_alloc( |
| isl_ctx *ctx, int min_size); |
| __isl_give isl_id_to_ast_expr *isl_id_to_ast_expr_copy( |
| __isl_keep isl_id_to_ast_expr *id2expr); |
| __isl_null isl_id_to_ast_expr *isl_id_to_ast_expr_free( |
| __isl_take isl_id_to_ast_expr *id2expr); |
| |
| The C<min_size> argument to C<isl_id_to_ast_expr_alloc> can be used |
| to specify the expected size of the associative array. |
| The associative array will be grown automatically as needed. |
| |
| Associative arrays can be inspected using the following functions. |
| |
| #include <isl/id_to_ast_expr.h> |
| __isl_give isl_maybe_isl_ast_expr |
| isl_id_to_ast_expr_try_get( |
| __isl_keep isl_id_to_ast_expr *id2expr, |
| __isl_keep isl_id *key); |
| isl_bool isl_id_to_ast_expr_has( |
| __isl_keep isl_id_to_ast_expr *id2expr, |
| __isl_keep isl_id *key); |
| __isl_give isl_ast_expr *isl_id_to_ast_expr_get( |
| __isl_keep isl_id_to_ast_expr *id2expr, |
| __isl_take isl_id *key); |
| isl_stat isl_id_to_ast_expr_foreach( |
| __isl_keep isl_id_to_ast_expr *id2expr, |
| isl_stat (*fn)(__isl_take isl_id *key, |
| __isl_take isl_ast_expr *val, void *user), |
| void *user); |
| |
| The function C<isl_id_to_ast_expr_try_get> returns a structure |
| containing two elements, C<valid> and C<value>. |
| If there is a value associated to the key, then C<valid> |
| is set to C<isl_bool_true> and C<value> contains a copy of |
| the associated value. Otherwise C<value> is C<NULL> and |
| C<valid> may be C<isl_bool_error> or C<isl_bool_false> depending |
| on whether some error has occurred or there simply is no associated value. |
| The function C<isl_id_to_ast_expr_has> returns the C<valid> field |
| in the structure and |
| the function C<isl_id_to_ast_expr_get> returns the C<value> field. |
| |
| Associative arrays can be modified using the following functions. |
| |
| #include <isl/id_to_ast_expr.h> |
| __isl_give isl_id_to_ast_expr *isl_id_to_ast_expr_set( |
| __isl_take isl_id_to_ast_expr *id2expr, |
| __isl_take isl_id *key, |
| __isl_take isl_ast_expr *val); |
| __isl_give isl_id_to_ast_expr *isl_id_to_ast_expr_drop( |
| __isl_take isl_id_to_ast_expr *id2expr, |
| __isl_take isl_id *key); |
| |
| Associative arrays can be printed using the following function. |
| |
| #include <isl/id_to_ast_expr.h> |
| __isl_give isl_printer *isl_printer_print_id_to_ast_expr( |
| __isl_take isl_printer *p, |
| __isl_keep isl_id_to_ast_expr *id2expr); |
| |
| =head2 Vectors |
| |
| Vectors can be created, copied and freed using the following functions. |
| |
| #include <isl/vec.h> |
| __isl_give isl_vec *isl_vec_alloc(isl_ctx *ctx, |
| unsigned size); |
| __isl_give isl_vec *isl_vec_zero(isl_ctx *ctx, |
| unsigned size); |
| __isl_give isl_vec *isl_vec_copy(__isl_keep isl_vec *vec); |
| __isl_null isl_vec *isl_vec_free(__isl_take isl_vec *vec); |
| |
| Note that the elements of a vector created by C<isl_vec_alloc> |
| may have arbitrary values. |
| A vector created by C<isl_vec_zero> has elements with value zero. |
| The elements can be changed and inspected using the following functions. |
| |
| int isl_vec_size(__isl_keep isl_vec *vec); |
| __isl_give isl_val *isl_vec_get_element_val( |
| __isl_keep isl_vec *vec, int pos); |
| __isl_give isl_vec *isl_vec_set_element_si( |
| __isl_take isl_vec *vec, int pos, int v); |
| __isl_give isl_vec *isl_vec_set_element_val( |
| __isl_take isl_vec *vec, int pos, |
| __isl_take isl_val *v); |
| __isl_give isl_vec *isl_vec_set_si(__isl_take isl_vec *vec, |
| int v); |
| __isl_give isl_vec *isl_vec_set_val( |
| __isl_take isl_vec *vec, __isl_take isl_val *v); |
| int isl_vec_cmp_element(__isl_keep isl_vec *vec1, |
| __isl_keep isl_vec *vec2, int pos); |
| |
| C<isl_vec_get_element> will return a negative value if anything went wrong. |
| In that case, the value of C<*v> is undefined. |
| |
| The following function can be used to concatenate two vectors. |
| |
| __isl_give isl_vec *isl_vec_concat(__isl_take isl_vec *vec1, |
| __isl_take isl_vec *vec2); |
| |
| =head2 Matrices |
| |
| Matrices can be created, copied and freed using the following functions. |
| |
| #include <isl/mat.h> |
| __isl_give isl_mat *isl_mat_alloc(isl_ctx *ctx, |
| unsigned n_row, unsigned n_col); |
| __isl_give isl_mat *isl_mat_copy(__isl_keep isl_mat *mat); |
| __isl_null isl_mat *isl_mat_free(__isl_take isl_mat *mat); |
| |
| Note that the elements of a newly created matrix may have arbitrary values. |
| The elements can be changed and inspected using the following functions. |
| |
| int isl_mat_rows(__isl_keep isl_mat *mat); |
| int isl_mat_cols(__isl_keep isl_mat *mat); |
| __isl_give isl_val *isl_mat_get_element_val( |
| __isl_keep isl_mat *mat, int row, int col); |
| __isl_give isl_mat *isl_mat_set_element_si(__isl_take isl_mat *mat, |
| int row, int col, int v); |
| __isl_give isl_mat *isl_mat_set_element_val( |
| __isl_take isl_mat *mat, int row, int col, |
| __isl_take isl_val *v); |
| |
| The following function computes the rank of a matrix. |
| The return value may be -1 if some error occurred. |
| |
| #include <isl/mat.h> |
| int isl_mat_rank(__isl_keep isl_mat *mat); |
| |
| The following function can be used to compute the (right) inverse |
| of a matrix, i.e., a matrix such that the product of the original |
| and the inverse (in that order) is a multiple of the identity matrix. |
| The input matrix is assumed to be of full row-rank. |
| |
| __isl_give isl_mat *isl_mat_right_inverse(__isl_take isl_mat *mat); |
| |
| The following function can be used to compute the (right) kernel |
| (or null space) of a matrix, i.e., a matrix such that the product of |
| the original and the kernel (in that order) is the zero matrix. |
| |
| __isl_give isl_mat *isl_mat_right_kernel(__isl_take isl_mat *mat); |
| |
| The following function computes a basis for the space spanned |
| by the rows of a matrix. |
| |
| __isl_give isl_mat *isl_mat_row_basis( |
| __isl_take isl_mat *mat); |
| |
| The following function computes rows that extend a basis of C<mat1> |
| to a basis that also covers C<mat2>. |
| |
| __isl_give isl_mat *isl_mat_row_basis_extension( |
| __isl_take isl_mat *mat1, |
| __isl_take isl_mat *mat2); |
| |
| The following function checks whether there is no linear dependence |
| among the combined rows of "mat1" and "mat2" that is not already present |
| in "mat1" or "mat2" individually. |
| If "mat1" and "mat2" have linearly independent rows by themselves, |
| then this means that there is no linear dependence among all rows together. |
| |
| isl_bool isl_mat_has_linearly_independent_rows( |
| __isl_keep isl_mat *mat1, |
| __isl_keep isl_mat *mat2); |
| |
| =head2 Bounds on Piecewise Quasipolynomials and Piecewise Quasipolynomial Reductions |
| |
| The following functions determine |
| an upper or lower bound on a quasipolynomial over its domain. |
| |
| __isl_give isl_pw_qpolynomial_fold * |
| isl_pw_qpolynomial_bound( |
| __isl_take isl_pw_qpolynomial *pwqp, |
| enum isl_fold type, int *tight); |
| |
| __isl_give isl_union_pw_qpolynomial_fold * |
| isl_union_pw_qpolynomial_bound( |
| __isl_take isl_union_pw_qpolynomial *upwqp, |
| enum isl_fold type, int *tight); |
| |
| The C<type> argument may be either C<isl_fold_min> or C<isl_fold_max>. |
| If C<tight> is not C<NULL>, then C<*tight> is set to C<1> |
| is the returned bound is known be tight, i.e., for each value |
| of the parameters there is at least |
| one element in the domain that reaches the bound. |
| If the domain of C<pwqp> is not wrapping, then the bound is computed |
| over all elements in that domain and the result has a purely parametric |
| domain. If the domain of C<pwqp> is wrapping, then the bound is |
| computed over the range of the wrapped relation. The domain of the |
| wrapped relation becomes the domain of the result. |
| |
| =head2 Parametric Vertex Enumeration |
| |
| The parametric vertex enumeration described in this section |
| is mainly intended to be used internally and by the C<barvinok> |
| library. |
| |
| #include <isl/vertices.h> |
| __isl_give isl_vertices *isl_basic_set_compute_vertices( |
| __isl_keep isl_basic_set *bset); |
| |
| The function C<isl_basic_set_compute_vertices> performs the |
| actual computation of the parametric vertices and the chamber |
| decomposition and stores the result in an C<isl_vertices> object. |
| This information can be queried by either iterating over all |
| the vertices or iterating over all the chambers or cells |
| and then iterating over all vertices that are active on the chamber. |
| |
| isl_stat isl_vertices_foreach_vertex( |
| __isl_keep isl_vertices *vertices, |
| isl_stat (*fn)(__isl_take isl_vertex *vertex, |
| void *user), void *user); |
| |
| isl_stat isl_vertices_foreach_cell( |
| __isl_keep isl_vertices *vertices, |
| isl_stat (*fn)(__isl_take isl_cell *cell, |
| void *user), void *user); |
| isl_stat isl_cell_foreach_vertex(__isl_keep isl_cell *cell, |
| isl_stat (*fn)(__isl_take isl_vertex *vertex, |
| void *user), void *user); |
| |
| Other operations that can be performed on an C<isl_vertices> object are |
| the following. |
| |
| int isl_vertices_get_n_vertices( |
| __isl_keep isl_vertices *vertices); |
| __isl_null isl_vertices *isl_vertices_free( |
| __isl_take isl_vertices *vertices); |
| |
| Vertices can be inspected and destroyed using the following functions. |
| |
| int isl_vertex_get_id(__isl_keep isl_vertex *vertex); |
| __isl_give isl_basic_set *isl_vertex_get_domain( |
| __isl_keep isl_vertex *vertex); |
| __isl_give isl_multi_aff *isl_vertex_get_expr( |
| __isl_keep isl_vertex *vertex); |
| void isl_vertex_free(__isl_take isl_vertex *vertex); |
| |
| C<isl_vertex_get_expr> returns a multiple quasi-affine expression |
| describing the vertex in terms of the parameters, |
| while C<isl_vertex_get_domain> returns the activity domain |
| of the vertex. |
| |
| Chambers can be inspected and destroyed using the following functions. |
| |
| __isl_give isl_basic_set *isl_cell_get_domain( |
| __isl_keep isl_cell *cell); |
| void isl_cell_free(__isl_take isl_cell *cell); |
| |
| =head1 Polyhedral Compilation Library |
| |
| This section collects functionality in C<isl> that has been specifically |
| designed for use during polyhedral compilation. |
| |
| =head2 Schedule Trees |
| |
| A schedule tree is a structured representation of a schedule, |
| assigning a relative order to a set of domain elements. |
| The relative order expressed by the schedule tree is |
| defined recursively. In particular, the order between |
| two domain elements is determined by the node that is closest |
| to the root that refers to both elements and that orders them apart. |
| Each node in the tree is of one of several types. |
| The root node is always of type C<isl_schedule_node_domain> |
| (or C<isl_schedule_node_extension>) |
| and it describes the (extra) domain elements to which the schedule applies. |
| The other types of nodes are as follows. |
| |
| =over |
| |
| =item C<isl_schedule_node_band> |
| |
| A band of schedule dimensions. Each schedule dimension is represented |
| by a union piecewise quasi-affine expression. If this expression |
| assigns a different value to two domain elements, while all previous |
| schedule dimensions in the same band assign them the same value, |
| then the two domain elements are ordered according to these two |
| different values. |
| Each expression is required to be total in the domain elements |
| that reach the band node. |
| |
| =item C<isl_schedule_node_expansion> |
| |
| An expansion node maps each of the domain elements that reach the node |
| to one or more domain elements. The image of this mapping forms |
| the set of domain elements that reach the child of the expansion node. |
| The function that maps each of the expanded domain elements |
| to the original domain element from which it was expanded |
| is called the contraction. |
| |
| =item C<isl_schedule_node_filter> |
| |
| A filter node does not impose any ordering, but rather intersects |
| the set of domain elements that the current subtree refers to |
| with a given union set. The subtree of the filter node only |
| refers to domain elements in the intersection. |
| A filter node is typically only used as a child of a sequence or |
| set node. |
| |
| =item C<isl_schedule_node_leaf> |
| |
| A leaf of the schedule tree. Leaf nodes do not impose any ordering. |
| |
| =item C<isl_schedule_node_mark> |
| |
| A mark node can be used to attach any kind of information to a subtree |
| of the schedule tree. |
| |
| =item C<isl_schedule_node_sequence> |
| |
| A sequence node has one or more children, each of which is a filter node. |
| The filters on these filter nodes form a partition of |
| the domain elements that the current subtree refers to. |
| If two domain elements appear in distinct filters then the sequence |
| node orders them according to the child positions of the corresponding |
| filter nodes. |
| |
| =item C<isl_schedule_node_set> |
| |
| A set node is similar to a sequence node, except that |
| it expresses that domain elements appearing in distinct filters |
| may have any order. The order of the children of a set node |
| is therefore also immaterial. |
| |
| =back |
| |
| The following node types are only supported by the AST generator. |
| |
| =over |
| |
| =item C<isl_schedule_node_context> |
| |
| The context describes constraints on the parameters and |
| the schedule dimensions of outer |
| bands that the AST generator may assume to hold. It is also the only |
| kind of node that may introduce additional parameters. |
| The space of the context is that of the flat product of the outer |
| band nodes. In particular, if there are no outer band nodes, then |
| this space is the unnamed zero-dimensional space. |
| Since a context node references the outer band nodes, any tree |
| containing a context node is considered to be anchored. |
| |
| =item C<isl_schedule_node_extension> |
| |
| An extension node instructs the AST generator to add additional |
| domain elements that need to be scheduled. |
| The additional domain elements are described by the range of |
| the extension map in terms of the outer schedule dimensions, |
| i.e., the flat product of the outer band nodes. |
| Note that domain elements are added whenever the AST generator |
| reaches the extension node, meaning that there are still some |
| active domain elements for which an AST needs to be generated. |
| The conditions under which some domain elements are still active |
| may however not be completely described by the outer AST nodes |
| generated at that point. |
| Since an extension node references the outer band nodes, any tree |
| containing an extension node is considered to be anchored. |
| |
| An extension node may also appear as the root of a schedule tree, |
| when it is intended to be inserted into another tree |
| using C<isl_schedule_node_graft_before> or C<isl_schedule_node_graft_after>. |
| In this case, the domain of the extension node should |
| correspond to the flat product of the outer band nodes |
| in this other schedule tree at the point where the extension tree |
| will be inserted. |
| |
| =item C<isl_schedule_node_guard> |
| |
| The guard describes constraints on the parameters and |
| the schedule dimensions of outer |
| bands that need to be enforced by the outer nodes |
| in the generated AST. |
| That is, the part of the AST that is generated from descendants |
| of the guard node can assume that these constraints are satisfied. |
| The space of the guard is that of the flat product of the outer |
| band nodes. In particular, if there are no outer band nodes, then |
| this space is the unnamed zero-dimensional space. |
| Since a guard node references the outer band nodes, any tree |
| containing a guard node is considered to be anchored. |
| |
| =back |
| |
| Except for the C<isl_schedule_node_context> nodes, |
| none of the nodes may introduce any parameters that were not |
| already present in the root domain node. |
| |
| A schedule tree is encapsulated in an C<isl_schedule> object. |
| The simplest such objects, those with a tree consisting of single domain node, |
| can be created using the following functions with either an empty |
| domain or a given domain. |
| |
| #include <isl/schedule.h> |
| __isl_give isl_schedule *isl_schedule_empty( |
| __isl_take isl_space *space); |
| __isl_give isl_schedule *isl_schedule_from_domain( |
| __isl_take isl_union_set *domain); |
| |
| The function C<isl_schedule_constraints_compute_schedule> described |
| in L</"Scheduling"> can also be used to construct schedules. |
| |
| C<isl_schedule> objects may be copied and freed using the following functions. |
| |
| #include <isl/schedule.h> |
| __isl_give isl_schedule *isl_schedule_copy( |
| __isl_keep isl_schedule *sched); |
| __isl_null isl_schedule *isl_schedule_free( |
| __isl_take isl_schedule *sched); |
| |
| The following functions checks whether two C<isl_schedule> objects |
| are obviously the same. |
| |
| #include <isl/schedule.h> |
| isl_bool isl_schedule_plain_is_equal( |
| __isl_keep isl_schedule *schedule1, |
| __isl_keep isl_schedule *schedule2); |
| |
| The domain of the schedule, i.e., the domain described by the root node, |
| can be obtained using the following function. |
| |
| #include <isl/schedule.h> |
| __isl_give isl_union_set *isl_schedule_get_domain( |
| __isl_keep isl_schedule *schedule); |
| |
| An extra top-level band node (right underneath the domain node) can |
| be introduced into the schedule using the following function. |
| The schedule tree is assumed not to have any anchored nodes. |
| |
| #include <isl/schedule.h> |
| __isl_give isl_schedule * |
| isl_schedule_insert_partial_schedule( |
| __isl_take isl_schedule *schedule, |
| __isl_take isl_multi_union_pw_aff *partial); |
| |
| A top-level context node (right underneath the domain node) can |
| be introduced into the schedule using the following function. |
| |
| #include <isl/schedule.h> |
| __isl_give isl_schedule *isl_schedule_insert_context( |
| __isl_take isl_schedule *schedule, |
| __isl_take isl_set *context) |
| |
| A top-level guard node (right underneath the domain node) can |
| be introduced into the schedule using the following function. |
| |
| #include <isl/schedule.h> |
| __isl_give isl_schedule *isl_schedule_insert_guard( |
| __isl_take isl_schedule *schedule, |
| __isl_take isl_set *guard) |
| |
| A schedule that combines two schedules either in the given |
| order or in an arbitrary order, i.e., with an C<isl_schedule_node_sequence> |
| or an C<isl_schedule_node_set> node, |
| can be created using the following functions. |
| |
| #include <isl/schedule.h> |
| __isl_give isl_schedule *isl_schedule_sequence( |
| __isl_take isl_schedule *schedule1, |
| __isl_take isl_schedule *schedule2); |
| __isl_give isl_schedule *isl_schedule_set( |
| __isl_take isl_schedule *schedule1, |
| __isl_take isl_schedule *schedule2); |
| |
| The domains of the two input schedules need to be disjoint. |
| |
| The following function can be used to restrict the domain |
| of a schedule with a domain node as root to be a subset of the given union set. |
| This operation may remove nodes in the tree that have become |
| redundant. |
| |
| #include <isl/schedule.h> |
| __isl_give isl_schedule *isl_schedule_intersect_domain( |
| __isl_take isl_schedule *schedule, |
| __isl_take isl_union_set *domain); |
| |
| The following function can be used to simplify the domain |
| of a schedule with a domain node as root with respect to the given |
| parameter domain. |
| |
| #include <isl/schedule.h> |
| __isl_give isl_schedule *isl_schedule_gist_domain_params( |
| __isl_take isl_schedule *schedule, |
| __isl_take isl_set *context); |
| |
| The following function resets the user pointers on all parameter |
| and tuple identifiers referenced by the nodes of the given schedule. |
| |
| #include <isl/schedule.h> |
| __isl_give isl_schedule *isl_schedule_reset_user( |
| __isl_take isl_schedule *schedule); |
| |
| The following function aligns the parameters of all nodes |
| in the given schedule to the given space. |
| |
| #include <isl/schedule.h> |
| __isl_give isl_schedule *isl_schedule_align_params( |
| __isl_take isl_schedule *schedule, |
| __isl_take isl_space *space); |
| |
| The following function allows the user to plug in a given function |
| in the iteration domains. The input schedule is not allowed to contain |
| any expansion nodes. |
| |
| #include <isl/schedule.h> |
| __isl_give isl_schedule * |
| isl_schedule_pullback_union_pw_multi_aff( |
| __isl_take isl_schedule *schedule, |
| __isl_take isl_union_pw_multi_aff *upma); |
| |
| The following function can be used to plug in the schedule C<expansion> |
| in the leaves of C<schedule>, where C<contraction> describes how |
| the domain elements of C<expansion> map to the domain elements |
| at the original leaves of C<schedule>. |
| The resulting schedule will contain expansion nodes, unless |
| C<contraction> is an identity function. |
| |
| #include <isl/schedule.h> |
| __isl_give isl_schedule *isl_schedule_expand( |
| __isl_take isl_schedule *schedule, |
| __isl_take isl_union_pw_multi_aff *contraction, |
| __isl_take isl_schedule *expansion); |
| |
| An C<isl_union_map> representation of the schedule can be obtained |
| from an C<isl_schedule> using the following function. |
| |
| #include <isl/schedule.h> |
| __isl_give isl_union_map *isl_schedule_get_map( |
| __isl_keep isl_schedule *sched); |
| |
| The resulting relation encodes the same relative ordering as |
| the schedule by mapping the domain elements to a common schedule space. |
| If the schedule_separate_components option is set, then the order |
| of the children of a set node is explicitly encoded in the result. |
| If the tree contains any expansion nodes, then the relation |
| is formulated in terms of the expanded domain elements. |
| |
| Schedules can be read from input using the following functions. |
| |
| #include <isl/schedule.h> |
| __isl_give isl_schedule *isl_schedule_read_from_file( |
| isl_ctx *ctx, FILE *input); |
| __isl_give isl_schedule *isl_schedule_read_from_str( |
| isl_ctx *ctx, const char *str); |
| |
| A representation of the schedule can be printed using |
| |
| #include <isl/schedule.h> |
| __isl_give isl_printer *isl_printer_print_schedule( |
| __isl_take isl_printer *p, |
| __isl_keep isl_schedule *schedule); |
| __isl_give char *isl_schedule_to_str( |
| __isl_keep isl_schedule *schedule); |
| |
| C<isl_schedule_to_str> prints the schedule in flow format. |
| |
| The schedule tree can be traversed through the use of |
| C<isl_schedule_node> objects that point to a particular |
| position in the schedule tree. Whenever a C<isl_schedule_node> |
| is used to modify a node in the schedule tree, the original schedule |
| tree is left untouched and the modifications are performed to a copy |
| of the tree. The returned C<isl_schedule_node> then points to |
| this modified copy of the tree. |
| |
| The root of the schedule tree can be obtained using the following function. |
| |
| #include <isl/schedule.h> |
| __isl_give isl_schedule_node *isl_schedule_get_root( |
| __isl_keep isl_schedule *schedule); |
| |
| A pointer to a newly created schedule tree with a single domain |
| node can be created using the following functions. |
| |
| #include <isl/schedule_node.h> |
| __isl_give isl_schedule_node * |
| isl_schedule_node_from_domain( |
| __isl_take isl_union_set *domain); |
| __isl_give isl_schedule_node * |
| isl_schedule_node_from_extension( |
| __isl_take isl_union_map *extension); |
| |
| C<isl_schedule_node_from_extension> creates a tree with an extension |
| node as root. |
| |
| Schedule nodes can be copied and freed using the following functions. |
| |
| #include <isl/schedule_node.h> |
| __isl_give isl_schedule_node *isl_schedule_node_copy( |
| __isl_keep isl_schedule_node *node); |
| __isl_null isl_schedule_node *isl_schedule_node_free( |
| __isl_take isl_schedule_node *node); |
| |
| The following functions can be used to check if two schedule |
| nodes point to the same position in the same schedule. |
| |
| #include <isl/schedule_node.h> |
| isl_bool isl_schedule_node_is_equal( |
| __isl_keep isl_schedule_node *node1, |
| __isl_keep isl_schedule_node *node2); |
| |
| The following properties can be obtained from a schedule node. |
| |
| #include <isl/schedule_node.h> |
| enum isl_schedule_node_type isl_schedule_node_get_type( |
| __isl_keep isl_schedule_node *node); |
| enum isl_schedule_node_type |
| isl_schedule_node_get_parent_type( |
| __isl_keep isl_schedule_node *node); |
| __isl_give isl_schedule *isl_schedule_node_get_schedule( |
| __isl_keep isl_schedule_node *node); |
| |
| The function C<isl_schedule_node_get_type> returns the type of |
| the node, while C<isl_schedule_node_get_parent_type> returns |
| type of the parent of the node, which is required to exist. |
| The function C<isl_schedule_node_get_schedule> returns a copy |
| to the schedule to which the node belongs. |
| |
| The following functions can be used to move the schedule node |
| to a different position in the tree or to check if such a position |
| exists. |
| |
| #include <isl/schedule_node.h> |
| isl_bool isl_schedule_node_has_parent( |
| __isl_keep isl_schedule_node *node); |
| __isl_give isl_schedule_node *isl_schedule_node_parent( |
| __isl_take isl_schedule_node *node); |
| __isl_give isl_schedule_node *isl_schedule_node_root( |
| __isl_take isl_schedule_node *node); |
| __isl_give isl_schedule_node *isl_schedule_node_ancestor( |
| __isl_take isl_schedule_node *node, |
| int generation); |
| int isl_schedule_node_n_children( |
| __isl_keep isl_schedule_node *node); |
| __isl_give isl_schedule_node *isl_schedule_node_child( |
| __isl_take isl_schedule_node *node, int pos); |
| isl_bool isl_schedule_node_has_children( |
| __isl_keep isl_schedule_node *node); |
| __isl_give isl_schedule_node *isl_schedule_node_first_child( |
| __isl_take isl_schedule_node *node); |
| isl_bool isl_schedule_node_has_previous_sibling( |
| __isl_keep isl_schedule_node *node); |
| __isl_give isl_schedule_node * |
| isl_schedule_node_previous_sibling( |
| __isl_take isl_schedule_node *node); |
| isl_bool isl_schedule_node_has_next_sibling( |
| __isl_keep isl_schedule_node *node); |
| __isl_give isl_schedule_node * |
| isl_schedule_node_next_sibling( |
| __isl_take isl_schedule_node *node); |
| |
| For C<isl_schedule_node_ancestor>, the ancestor of generation 0 |
| is the node itself, the ancestor of generation 1 is its parent and so on. |
| |
| It is also possible to query the number of ancestors of a node, |
| the position of the current node |
| within the children of its parent, the position of the subtree |
| containing a node within the children of an ancestor |
| or to obtain a copy of a given |
| child without destroying the current node. |
| Given two nodes that point to the same schedule, their closest |
| shared ancestor can be obtained using |
| C<isl_schedule_node_get_shared_ancestor>. |
| |
| #include <isl/schedule_node.h> |
| int isl_schedule_node_get_tree_depth( |
| __isl_keep isl_schedule_node *node); |
| int isl_schedule_node_get_child_position( |
| __isl_keep isl_schedule_node *node); |
| int isl_schedule_node_get_ancestor_child_position( |
| __isl_keep isl_schedule_node *node, |
| __isl_keep isl_schedule_node *ancestor); |
| __isl_give isl_schedule_node *isl_schedule_node_get_child( |
| __isl_keep isl_schedule_node *node, int pos); |
| __isl_give isl_schedule_node * |
| isl_schedule_node_get_shared_ancestor( |
| __isl_keep isl_schedule_node *node1, |
| __isl_keep isl_schedule_node *node2); |
| |
| All nodes in a schedule tree or |
| all descendants of a specific node (including the node) can be visited |
| in depth-first pre-order using the following functions. |
| |
| #include <isl/schedule.h> |
| isl_stat isl_schedule_foreach_schedule_node_top_down( |
| __isl_keep isl_schedule *sched, |
| isl_bool (*fn)(__isl_keep isl_schedule_node *node, |
| void *user), void *user); |
| |
| #include <isl/schedule_node.h> |
| isl_stat isl_schedule_node_foreach_descendant_top_down( |
| __isl_keep isl_schedule_node *node, |
| isl_bool (*fn)(__isl_keep isl_schedule_node *node, |
| void *user), void *user); |
| |
| The callback function is slightly different from the usual |
| callbacks in that it not only indicates success (non-negative result) |
| or failure (negative result), but also indicates whether the children |
| of the given node should be visited. In particular, if the callback |
| returns a positive value, then the children are visited, but if |
| the callback returns zero, then the children are not visited. |
| |
| The following functions checks whether |
| all descendants of a specific node (including the node itself) |
| satisfy a user-specified test. |
| |
| #include <isl/schedule_node.h> |
| isl_bool isl_schedule_node_every_descendant( |
| __isl_keep isl_schedule_node *node, |
| isl_bool (*test)(__isl_keep isl_schedule_node *node, |
| void *user), void *user) |
| |
| The ancestors of a node in a schedule tree can be visited from |
| the root down to and including the parent of the node using |
| the following function. |
| |
| #include <isl/schedule_node.h> |
| isl_stat isl_schedule_node_foreach_ancestor_top_down( |
| __isl_keep isl_schedule_node *node, |
| isl_stat (*fn)(__isl_keep isl_schedule_node *node, |
| void *user), void *user); |
| |
| The following functions allows for a depth-first post-order |
| traversal of the nodes in a schedule tree or |
| of the descendants of a specific node (including the node |
| itself), where the user callback is allowed to modify the |
| visited node. |
| |
| #include <isl/schedule.h> |
| __isl_give isl_schedule * |
| isl_schedule_map_schedule_node_bottom_up( |
| __isl_take isl_schedule *schedule, |
| __isl_give isl_schedule_node *(*fn)( |
| __isl_take isl_schedule_node *node, |
| void *user), void *user); |
| |
| #include <isl/schedule_node.h> |
| __isl_give isl_schedule_node * |
| isl_schedule_node_map_descendant_bottom_up( |
| __isl_take isl_schedule_node *node, |
| __isl_give isl_schedule_node *(*fn)( |
| __isl_take isl_schedule_node *node, |
| void *user), void *user); |
| |
| The traversal continues from the node returned by the callback function. |
| It is the responsibility of the user to ensure that this does not |
| lead to an infinite loop. It is safest to always return a pointer |
| to the same position (same ancestors and child positions) as the input node. |
| |
| The following function removes a node (along with its descendants) |
| from a schedule tree and returns a pointer to the leaf at the |
| same position in the updated tree. |
| It is not allowed to remove the root of a schedule tree or |
| a child of a set or sequence node. |
| |
| #include <isl/schedule_node.h> |
| __isl_give isl_schedule_node *isl_schedule_node_cut( |
| __isl_take isl_schedule_node *node); |
| |
| The following function removes a single node |
| from a schedule tree and returns a pointer to the child |
| of the node, now located at the position of the original node |
| or to a leaf node at that position if there was no child. |
| It is not allowed to remove the root of a schedule tree, |
| a set or sequence node, a child of a set or sequence node or |
| a band node with an anchored subtree. |
| |
| #include <isl/schedule_node.h> |
| __isl_give isl_schedule_node *isl_schedule_node_delete( |
| __isl_take isl_schedule_node *node); |
| |
| Most nodes in a schedule tree only contain local information. |
| In some cases, however, a node may also refer to the schedule dimensions |
| of its outer band nodes. |
| This means that the position of the node within the tree should |
| not be changed, or at least that no changes are performed to the |
| outer band nodes. The following function can be used to test |
| whether the subtree rooted at a given node contains any such nodes. |
| |
| #include <isl/schedule_node.h> |
| isl_bool isl_schedule_node_is_subtree_anchored( |
| __isl_keep isl_schedule_node *node); |
| |
| The following function resets the user pointers on all parameter |
| and tuple identifiers referenced by the given schedule node. |
| |
| #include <isl/schedule_node.h> |
| __isl_give isl_schedule_node *isl_schedule_node_reset_user( |
| __isl_take isl_schedule_node *node); |
| |
| The following function aligns the parameters of the given schedule |
| node to the given space. |
| |
| #include <isl/schedule_node.h> |
| __isl_give isl_schedule_node * |
| isl_schedule_node_align_params( |
| __isl_take isl_schedule_node *node, |
| __isl_take isl_space *space); |
| |
| Several node types have their own functions for querying |
| (and in some cases setting) some node type specific properties. |
| |
| #include <isl/schedule_node.h> |
| __isl_give isl_space *isl_schedule_node_band_get_space( |
| __isl_keep isl_schedule_node *node); |
| __isl_give isl_multi_union_pw_aff * |
| isl_schedule_node_band_get_partial_schedule( |
| __isl_keep isl_schedule_node *node); |
| __isl_give isl_union_map * |
| isl_schedule_node_band_get_partial_schedule_union_map( |
| __isl_keep isl_schedule_node *node); |
| unsigned isl_schedule_node_band_n_member( |
| __isl_keep isl_schedule_node *node); |
| isl_bool isl_schedule_node_band_member_get_coincident( |
| __isl_keep isl_schedule_node *node, int pos); |
| __isl_give isl_schedule_node * |
| isl_schedule_node_band_member_set_coincident( |
| __isl_take isl_schedule_node *node, int pos, |
| int coincident); |
| isl_bool isl_schedule_node_band_get_permutable( |
| __isl_keep isl_schedule_node *node); |
| __isl_give isl_schedule_node * |
| isl_schedule_node_band_set_permutable( |
| __isl_take isl_schedule_node *node, int permutable); |
| enum isl_ast_loop_type |
| isl_schedule_node_band_member_get_ast_loop_type( |
| __isl_keep isl_schedule_node *node, int pos); |
| __isl_give isl_schedule_node * |
| isl_schedule_node_band_member_set_ast_loop_type( |
| __isl_take isl_schedule_node *node, int pos, |
| enum isl_ast_loop_type type); |
| __isl_give isl_union_set * |
| enum isl_ast_loop_type |
| isl_schedule_node_band_member_get_isolate_ast_loop_type( |
| __isl_keep isl_schedule_node *node, int pos); |
| __isl_give isl_schedule_node * |
| isl_schedule_node_band_member_set_isolate_ast_loop_type( |
| __isl_take isl_schedule_node *node, int pos, |
| enum isl_ast_loop_type type); |
| isl_schedule_node_band_get_ast_build_options( |
| __isl_keep isl_schedule_node *node); |
| __isl_give isl_schedule_node * |
| isl_schedule_node_band_set_ast_build_options( |
| __isl_take isl_schedule_node *node, |
| __isl_take isl_union_set *options); |
| __isl_give isl_set * |
| isl_schedule_node_band_get_ast_isolate_option( |
| __isl_keep isl_schedule_node *node); |
| |
| The function C<isl_schedule_node_band_get_space> returns the space |
| of the partial schedule of the band. |
| The function C<isl_schedule_node_band_get_partial_schedule_union_map> |
| returns a representation of the partial schedule of the band node |
| in the form of an C<isl_union_map>. |
| The coincident and permutable properties are set by |
| C<isl_schedule_constraints_compute_schedule> on the schedule tree |
| it produces. |
| A scheduling dimension is considered to be ``coincident'' |
| if it satisfies the coincidence constraints within its band. |
| That is, if the dependence distances of the coincidence |
| constraints are all zero in that direction (for fixed |
| iterations of outer bands). |
| A band is marked permutable if it was produced using the Pluto-like scheduler. |
| Note that the scheduler may have to resort to a Feautrier style scheduling |
| step even if the default scheduler is used. |
| An C<isl_ast_loop_type> is one of C<isl_ast_loop_default>, |
| C<isl_ast_loop_atomic>, C<isl_ast_loop_unroll> or C<isl_ast_loop_separate>. |
| For the meaning of these loop AST generation types and the difference |
| between the regular loop AST generation type and the isolate |
| loop AST generation type, see L</"AST Generation Options (Schedule Tree)">. |
| The functions C<isl_schedule_node_band_member_get_ast_loop_type> |
| and C<isl_schedule_node_band_member_get_isolate_ast_loop_type> |
| may return C<isl_ast_loop_error> if an error occurs. |
| The AST build options govern how an AST is generated for |
| the individual schedule dimensions during AST generation. |
| See L</"AST Generation Options (Schedule Tree)">. |
| The isolate option for the given node can be extracted from these |
| AST build options using the function |
| C<isl_schedule_node_band_get_ast_isolate_option>. |
| |
| #include <isl/schedule_node.h> |
| __isl_give isl_set * |
| isl_schedule_node_context_get_context( |
| __isl_keep isl_schedule_node *node); |
| |
| #include <isl/schedule_node.h> |
| __isl_give isl_union_set * |
| isl_schedule_node_domain_get_domain( |
| __isl_keep isl_schedule_node *node); |
| |
| #include <isl/schedule_node.h> |
| __isl_give isl_union_map * |
| isl_schedule_node_expansion_get_expansion( |
| __isl_keep isl_schedule_node *node); |
| __isl_give isl_union_pw_multi_aff * |
| isl_schedule_node_expansion_get_contraction( |
| __isl_keep isl_schedule_node *node); |
| |
| #include <isl/schedule_node.h> |
| __isl_give isl_union_map * |
| isl_schedule_node_extension_get_extension( |
| __isl_keep isl_schedule_node *node); |
| |
| #include <isl/schedule_node.h> |
| __isl_give isl_union_set * |
| isl_schedule_node_filter_get_filter( |
| __isl_keep isl_schedule_node *node); |
| |
| #include <isl/schedule_node.h> |
| __isl_give isl_set *isl_schedule_node_guard_get_guard( |
| __isl_keep isl_schedule_node *node); |
| |
| #include <isl/schedule_node.h> |
| __isl_give isl_id *isl_schedule_node_mark_get_id( |
| __isl_keep isl_schedule_node *node); |
| |
| The following functions can be used to obtain an C<isl_multi_union_pw_aff>, |
| an C<isl_union_pw_multi_aff> or C<isl_union_map> representation of |
| partial schedules related to the node. |
| |
| #include <isl/schedule_node.h> |
| __isl_give isl_multi_union_pw_aff * |
| isl_schedule_node_get_prefix_schedule_multi_union_pw_aff( |
| __isl_keep isl_schedule_node *node); |
| __isl_give isl_union_pw_multi_aff * |
| isl_schedule_node_get_prefix_schedule_union_pw_multi_aff( |
| __isl_keep isl_schedule_node *node); |
| __isl_give isl_union_map * |
| isl_schedule_node_get_prefix_schedule_union_map( |
| __isl_keep isl_schedule_node *node); |
| __isl_give isl_union_map * |
| isl_schedule_node_get_prefix_schedule_relation( |
| __isl_keep isl_schedule_node *node); |
| __isl_give isl_union_map * |
| isl_schedule_node_get_subtree_schedule_union_map( |
| __isl_keep isl_schedule_node *node); |
| |
| In particular, the functions |
| C<isl_schedule_node_get_prefix_schedule_multi_union_pw_aff>, |
| C<isl_schedule_node_get_prefix_schedule_union_pw_multi_aff> |
| and C<isl_schedule_node_get_prefix_schedule_union_map> |
| return a relative ordering on the domain elements that reach the given |
| node determined by its ancestors. |
| The function C<isl_schedule_node_get_prefix_schedule_relation> |
| additionally includes the domain constraints in the result. |
| The function C<isl_schedule_node_get_subtree_schedule_union_map> |
| returns a representation of the partial schedule defined by the |
| subtree rooted at the given node. |
| If the tree contains any expansion nodes, then the subtree schedule |
| is formulated in terms of the expanded domain elements. |
| The tree passed to functions returning a prefix schedule |
| may only contain extension nodes if these would not affect |
| the result of these functions. That is, if one of the ancestors |
| is an extension node, then all of the domain elements that were |
| added by the extension node need to have been filtered out |
| by filter nodes between the extension node and the input node. |
| The tree passed to C<isl_schedule_node_get_subtree_schedule_union_map> |
| may not contain in extension nodes in the selected subtree. |
| |
| The expansion/contraction defined by an entire subtree, combining |
| the expansions/contractions |
| on the expansion nodes in the subtree, can be obtained using |
| the following functions. |
| |
| #include <isl/schedule_node.h> |
| __isl_give isl_union_map * |
| isl_schedule_node_get_subtree_expansion( |
| __isl_keep isl_schedule_node *node); |
| __isl_give isl_union_pw_multi_aff * |
| isl_schedule_node_get_subtree_contraction( |
| __isl_keep isl_schedule_node *node); |
| |
| The total number of outer band members of given node, i.e., |
| the shared output dimension of the maps in the result |
| of C<isl_schedule_node_get_prefix_schedule_union_map> can be obtained |
| using the following function. |
| |
| #include <isl/schedule_node.h> |
| int isl_schedule_node_get_schedule_depth( |
| __isl_keep isl_schedule_node *node); |
| |
| The following functions return the elements that reach the given node |
| or the union of universes in the spaces that contain these elements. |
| |
| #include <isl/schedule_node.h> |
| __isl_give isl_union_set * |
| isl_schedule_node_get_domain( |
| __isl_keep isl_schedule_node *node); |
| __isl_give isl_union_set * |
| isl_schedule_node_get_universe_domain( |
| __isl_keep isl_schedule_node *node); |
| |
| The input tree of C<isl_schedule_node_get_domain> |
| may only contain extension nodes if these would not affect |
| the result of this function. That is, if one of the ancestors |
| is an extension node, then all of the domain elements that were |
| added by the extension node need to have been filtered out |
| by filter nodes between the extension node and the input node. |
| |
| The following functions can be used to introduce additional nodes |
| in the schedule tree. The new node is introduced at the point |
| in the tree where the C<isl_schedule_node> points to and |
| the results points to the new node. |
| |
| #include <isl/schedule_node.h> |
| __isl_give isl_schedule_node * |
| isl_schedule_node_insert_partial_schedule( |
| __isl_take isl_schedule_node *node, |
| __isl_take isl_multi_union_pw_aff *schedule); |
| |
| This function inserts a new band node with (the greatest integer |
| part of) the given partial schedule. |
| The subtree rooted at the given node is assumed not to have |
| any anchored nodes. |
| |
| #include <isl/schedule_node.h> |
| __isl_give isl_schedule_node * |
| isl_schedule_node_insert_context( |
| __isl_take isl_schedule_node *node, |
| __isl_take isl_set *context); |
| |
| This function inserts a new context node with the given context constraints. |
| |
| #include <isl/schedule_node.h> |
| __isl_give isl_schedule_node * |
| isl_schedule_node_insert_filter( |
| __isl_take isl_schedule_node *node, |
| __isl_take isl_union_set *filter); |
| |
| This function inserts a new filter node with the given filter. |
| If the original node already pointed to a filter node, then the |
| two filter nodes are merged into one. |
| |
| #include <isl/schedule_node.h> |
| __isl_give isl_schedule_node * |
| isl_schedule_node_insert_guard( |
| __isl_take isl_schedule_node *node, |
| __isl_take isl_set *guard); |
| |
| This function inserts a new guard node with the given guard constraints. |
| |
| #include <isl/schedule_node.h> |
| __isl_give isl_schedule_node * |
| isl_schedule_node_insert_mark( |
| __isl_take isl_schedule_node *node, |
| __isl_take isl_id *mark); |
| |
| This function inserts a new mark node with the give mark identifier. |
| |
| #include <isl/schedule_node.h> |
| __isl_give isl_schedule_node * |
| isl_schedule_node_insert_sequence( |
| __isl_take isl_schedule_node *node, |
| __isl_take isl_union_set_list *filters); |
| __isl_give isl_schedule_node * |
| isl_schedule_node_insert_set( |
| __isl_take isl_schedule_node *node, |
| __isl_take isl_union_set_list *filters); |
| |
| These functions insert a new sequence or set node with the given |
| filters as children. |
| |
| #include <isl/schedule_node.h> |
| __isl_give isl_schedule_node *isl_schedule_node_group( |
| __isl_take isl_schedule_node *node, |
| __isl_take isl_id *group_id); |
| |
| This function introduces an expansion node in between the current |
| node and its parent that expands instances of a space with tuple |
| identifier C<group_id> to the original domain elements that reach |
| the node. The group instances are identified by the prefix schedule |
| of those domain elements. The ancestors of the node are adjusted |
| to refer to the group instances instead of the original domain |
| elements. The return value points to the same node in the updated |
| schedule tree as the input node, i.e., to the child of the newly |
| introduced expansion node. Grouping instances of different statements |
| ensures that they will be treated as a single statement by the |
| AST generator up to the point of the expansion node. |
| |
| The following function can be used to flatten a nested |
| sequence. |
| |
| #include <isl/schedule_node.h> |
| __isl_give isl_schedule_node * |
| isl_schedule_node_sequence_splice_child( |
| __isl_take isl_schedule_node *node, int pos); |
| |
| That is, given a sequence node C<node> that has another sequence node |
| in its child at position C<pos> (in particular, the child of that filter |
| node is a sequence node), attach the children of that other sequence |
| node as children of C<node>, replacing the original child at position |
| C<pos>. |
| |
| The partial schedule of a band node can be scaled (down) or reduced using |
| the following functions. |
| |
| #include <isl/schedule_node.h> |
| __isl_give isl_schedule_node * |
| isl_schedule_node_band_scale( |
| __isl_take isl_schedule_node *node, |
| __isl_take isl_multi_val *mv); |
| __isl_give isl_schedule_node * |
| isl_schedule_node_band_scale_down( |
| __isl_take isl_schedule_node *node, |
| __isl_take isl_multi_val *mv); |
| __isl_give isl_schedule_node * |
| isl_schedule_node_band_mod( |
| __isl_take isl_schedule_node *node, |
| __isl_take isl_multi_val *mv); |
| |
| The spaces of the two arguments need to match. |
| After scaling, the partial schedule is replaced by its greatest |
| integer part to ensure that the schedule remains integral. |
| |
| The partial schedule of a band node can be shifted by an |
| C<isl_multi_union_pw_aff> with a domain that is a superset |
| of the domain of the partial schedule using |
| the following function. |
| |
| #include <isl/schedule_node.h> |
| __isl_give isl_schedule_node * |
| isl_schedule_node_band_shift( |
| __isl_take isl_schedule_node *node, |
| __isl_take isl_multi_union_pw_aff *shift); |
| |
| A band node can be tiled using the following function. |
| |
| #include <isl/schedule_node.h> |
| __isl_give isl_schedule_node *isl_schedule_node_band_tile( |
| __isl_take isl_schedule_node *node, |
| __isl_take isl_multi_val *sizes); |
| |
| isl_stat isl_options_set_tile_scale_tile_loops(isl_ctx *ctx, |
| int val); |
| int isl_options_get_tile_scale_tile_loops(isl_ctx *ctx); |
| isl_stat isl_options_set_tile_shift_point_loops(isl_ctx *ctx, |
| int val); |
| int isl_options_get_tile_shift_point_loops(isl_ctx *ctx); |
| |
| The C<isl_schedule_node_band_tile> function tiles |
| the band using the given tile sizes inside its schedule. |
| A new child band node is created to represent the point loops and it is |
| inserted between the modified band and its children. |
| The subtree rooted at the given node is assumed not to have |
| any anchored nodes. |
| The C<tile_scale_tile_loops> option specifies whether the tile |
| loops iterators should be scaled by the tile sizes. |
| If the C<tile_shift_point_loops> option is set, then the point loops |
| are shifted to start at zero. |
| |
| A band node can be split into two nested band nodes |
| using the following function. |
| |
| #include <isl/schedule_node.h> |
| __isl_give isl_schedule_node *isl_schedule_node_band_split( |
| __isl_take isl_schedule_node *node, int pos); |
| |
| The resulting outer band node contains the first C<pos> dimensions of |
| the schedule of C<node> while the inner band contains the remaining dimensions. |
| The schedules of the two band nodes live in anonymous spaces. |
| The loop AST generation type options and the isolate option |
| are split over the two band nodes. |
| |
| A band node can be moved down to the leaves of the subtree rooted |
| at the band node using the following function. |
| |
| #include <isl/schedule_node.h> |
| __isl_give isl_schedule_node *isl_schedule_node_band_sink( |
| __isl_take isl_schedule_node *node); |
| |
| The subtree rooted at the given node is assumed not to have |
| any anchored nodes. |
| The result points to the node in the resulting tree that is in the same |
| position as the node pointed to by C<node> in the original tree. |
| |
| #include <isl/schedule_node.h> |
| __isl_give isl_schedule_node * |
| isl_schedule_node_order_before( |
| __isl_take isl_schedule_node *node, |
| __isl_take isl_union_set *filter); |
| __isl_give isl_schedule_node * |
| isl_schedule_node_order_after( |
| __isl_take isl_schedule_node *node, |
| __isl_take isl_union_set *filter); |
| |
| These functions split the domain elements that reach C<node> |
| into those that satisfy C<filter> and those that do not and |
| arranges for the elements that do satisfy the filter to be |
| executed before (in case of C<isl_schedule_node_order_before>) |
| or after (in case of C<isl_schedule_node_order_after>) |
| those that do not. The order is imposed by |
| a sequence node, possibly reusing the grandparent of C<node> |
| on two copies of the subtree attached to the original C<node>. |
| Both copies are simplified with respect to their filter. |
| |
| Return a pointer to the copy of the subtree that does not |
| satisfy C<filter>. If there is no such copy (because all |
| reaching domain elements satisfy the filter), then return |
| the original pointer. |
| |
| #include <isl/schedule_node.h> |
| __isl_give isl_schedule_node * |
| isl_schedule_node_graft_before( |
| __isl_take isl_schedule_node *node, |
| __isl_take isl_schedule_node *graft); |
| __isl_give isl_schedule_node * |
| isl_schedule_node_graft_after( |
| __isl_take isl_schedule_node *node, |
| __isl_take isl_schedule_node *graft); |
| |
| This function inserts the C<graft> tree into the tree containing C<node> |
| such that it is executed before (in case of C<isl_schedule_node_graft_before>) |
| or after (in case of C<isl_schedule_node_graft_after>) C<node>. |
| The root node of C<graft> |
| should be an extension node where the domain of the extension |
| is the flat product of all outer band nodes of C<node>. |
| The root node may also be a domain node. |
| The elements of the domain or the range of the extension may not |
| intersect with the domain elements that reach "node". |
| The schedule tree of C<graft> may not be anchored. |
| |
| The schedule tree of C<node> is modified to include an extension node |
| corresponding to the root node of C<graft> as a child of the original |
| parent of C<node>. The original node that C<node> points to and the |
| child of the root node of C<graft> are attached to this extension node |
| through a sequence, with appropriate filters and with the child |
| of C<graft> appearing before or after the original C<node>. |
| |
| If C<node> already appears inside a sequence that is the child of |
| an extension node and if the spaces of the new domain elements |
| do not overlap with those of the original domain elements, |
| then that extension node is extended with the new extension |
| rather than introducing a new segment of extension and sequence nodes. |
| |
| Return a pointer to the same node in the modified tree that |
| C<node> pointed to in the original tree. |
| |
| A representation of the schedule node can be printed using |
| |
| #include <isl/schedule_node.h> |
| __isl_give isl_printer *isl_printer_print_schedule_node( |
| __isl_take isl_printer *p, |
| __isl_keep isl_schedule_node *node); |
| __isl_give char *isl_schedule_node_to_str( |
| __isl_keep isl_schedule_node *node); |
| |
| C<isl_schedule_node_to_str> prints the schedule node in block format. |
| |
| =head2 Dependence Analysis |
| |
| C<isl> contains specialized functionality for performing |
| array dataflow analysis. That is, given a I<sink> access relation, |
| a collection of possible I<source> accesses and |
| a collection of I<kill> accesses, |
| C<isl> can compute relations that describe |
| for each iteration of the sink access, which iterations |
| of which of the source access relations may have |
| accessed the same data element before the given iteration |
| of the sink access without any intermediate kill of that data element. |
| The resulting dependence relations map source iterations |
| to either the corresponding sink iterations or |
| pairs of corresponding sink iterations and accessed data elements. |
| To compute standard flow dependences, the sink should be |
| a read, while the sources should be writes. |
| If no kills are specified, |
| then memory based dependence analysis is performed. |
| If, on the other hand, all sources are also kills, |
| then value based dependence analysis is performed. |
| If any of the source accesses are marked as being I<must> |
| accesses, then they are also treated as kills. |
| Furthermore, the specification of must-sources results |
| in the computation of must-dependences. |
| Only dependences originating in a must access not coscheduled |
| with any other access to the same element and without |
| any may accesses between the must access and the sink access |
| are considered to be must dependences. |
| |
| =head3 High-level Interface |
| |
| A high-level interface to dependence analysis is provided |
| by the following function. |
| |
| #include <isl/flow.h> |
| __isl_give isl_union_flow * |
| isl_union_access_info_compute_flow( |
| __isl_take isl_union_access_info *access); |
| |
| The input C<isl_union_access_info> object describes the sink |
| access relations, the source access relations and a schedule, |
| while the output C<isl_union_flow> object describes |
| the resulting dependence relations and the subsets of the |
| sink relations for which no source was found. |
| |
| An C<isl_union_access_info> is created, modified, copied and freed using |
| the following functions. |
| |
| #include <isl/flow.h> |
| __isl_give isl_union_access_info * |
| isl_union_access_info_from_sink( |
| __isl_take isl_union_map *sink); |
| __isl_give isl_union_access_info * |
| isl_union_access_info_set_kill( |
| __isl_take isl_union_access_info *access, |
| __isl_take isl_union_map *kill); |
| __isl_give isl_union_access_info * |
| isl_union_access_info_set_may_source( |
| __isl_take isl_union_access_info *access, |
| __isl_take isl_union_map *may_source); |
| __isl_give isl_union_access_info * |
| isl_union_access_info_set_must_source( |
| __isl_take isl_union_access_info *access, |
| __isl_take isl_union_map *must_source); |
| __isl_give isl_union_access_info * |
| isl_union_access_info_set_schedule( |
| __isl_take isl_union_access_info *access, |
| __isl_take isl_schedule *schedule); |
| __isl_give isl_union_access_info * |
| isl_union_access_info_set_schedule_map( |
| __isl_take isl_union_access_info *access, |
| __isl_take isl_union_map *schedule_map); |
| __isl_give isl_union_access_info * |
| isl_union_access_info_copy( |
| __isl_keep isl_union_access_info *access); |
| __isl_null isl_union_access_info * |
| isl_union_access_info_free( |
| __isl_take isl_union_access_info *access); |
| |
| The may sources set by C<isl_union_access_info_set_may_source> |
| do not need to include the must sources set by |
| C<isl_union_access_info_set_must_source> as a subset. |
| The kills set by C<isl_union_access_info_set_kill> may overlap |
| with the may-sources and/or must-sources. |
| The user is free not to call one (or more) of these functions, |
| in which case the corresponding set is kept to its empty default. |
| Similarly, the default schedule initialized by |
| C<isl_union_access_info_from_sink> is empty. |
| The current schedule is determined by the last call to either |
| C<isl_union_access_info_set_schedule> or |
| C<isl_union_access_info_set_schedule_map>. |
| The domain of the schedule corresponds to the domains of |
| the access relations. In particular, the domains of the access |
| relations are effectively intersected with the domain of the schedule |
| and only the resulting accesses are considered by the dependence analysis. |
| |
| An C<isl_union_access_info> object can be read from input |
| using the following function. |
| |
| #include <isl/flow.h> |
| __isl_give isl_union_access_info * |
| isl_union_access_info_read_from_file(isl_ctx *ctx, |
| FILE *input); |
| |
| A representation of the information contained in an object |
| of type C<isl_union_access_info> can be obtained using |
| |
| #include <isl/flow.h> |
| __isl_give isl_printer * |
| isl_printer_print_union_access_info( |
| __isl_take isl_printer *p, |
| __isl_keep isl_union_access_info *access); |
| __isl_give char *isl_union_access_info_to_str( |
| __isl_keep isl_union_access_info *access); |
| |
| C<isl_union_access_info_to_str> prints the information in flow format. |
| |
| The output of C<isl_union_access_info_compute_flow> can be examined, |
| copied, and freed using the following functions. |
| |
| #include <isl/flow.h> |
| __isl_give isl_union_map *isl_union_flow_get_must_dependence( |
| __isl_keep isl_union_flow *flow); |
| __isl_give isl_union_map *isl_union_flow_get_may_dependence( |
| __isl_keep isl_union_flow *flow); |
| __isl_give isl_union_map * |
| isl_union_flow_get_full_must_dependence( |
| __isl_keep isl_union_flow *flow); |
| __isl_give isl_union_map * |
| isl_union_flow_get_full_may_dependence( |
| __isl_keep isl_union_flow *flow); |
| __isl_give isl_union_map *isl_union_flow_get_must_no_source( |
| __isl_keep isl_union_flow *flow); |
| __isl_give isl_union_map *isl_union_flow_get_may_no_source( |
| __isl_keep isl_union_flow *flow); |
| __isl_give isl_union_flow *isl_union_flow_copy( |
| __isl_keep isl_union_flow *flow); |
| __isl_null isl_union_flow *isl_union_flow_free( |
| __isl_take isl_union_flow *flow); |
| |
| The relation returned by C<isl_union_flow_get_must_dependence> |
| relates domain elements of must sources to domain elements of the sink. |
| The relation returned by C<isl_union_flow_get_may_dependence> |
| relates domain elements of must or may sources to domain elements of the sink |
| and includes the previous relation as a subset. |
| The relation returned by C<isl_union_flow_get_full_must_dependence> |
| relates domain elements of must sources to pairs of domain elements of the sink |
| and accessed data elements. |
| The relation returned by C<isl_union_flow_get_full_may_dependence> |
| relates domain elements of must or may sources to pairs of |
| domain elements of the sink and accessed data elements. |
| This relation includes the previous relation as a subset. |
| The relation returned by C<isl_union_flow_get_must_no_source> is the subset |
| of the sink relation for which no dependences have been found. |
| The relation returned by C<isl_union_flow_get_may_no_source> is the subset |
| of the sink relation for which no definite dependences have been found. |
| That is, it contains those sink access that do not contribute to any |
| of the elements in the relation returned |
| by C<isl_union_flow_get_must_dependence>. |
| |
| A representation of the information contained in an object |
| of type C<isl_union_flow> can be obtained using |
| |
| #include <isl/flow.h> |
| __isl_give isl_printer *isl_printer_print_union_flow( |
| __isl_take isl_printer *p, |
| __isl_keep isl_union_flow *flow); |
| __isl_give char *isl_union_flow_to_str( |
| __isl_keep isl_union_flow *flow); |
| |
| C<isl_union_flow_to_str> prints the information in flow format. |
| |
| =head3 Low-level Interface |
| |
| A lower-level interface is provided by the following functions. |
| |
| #include <isl/flow.h> |
| |
| typedef int (*isl_access_level_before)(void *first, void *second); |
| |
| __isl_give isl_access_info *isl_access_info_alloc( |
| __isl_take isl_map *sink, |
| void *sink_user, isl_access_level_before fn, |
| int max_source); |
| __isl_give isl_access_info *isl_access_info_add_source( |
| __isl_take isl_access_info *acc, |
| __isl_take isl_map *source, int must, |
| void *source_user); |
| __isl_null isl_access_info *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_stat isl_flow_foreach(__isl_keep isl_flow *deps, |
| isl_stat (*fn)(__isl_take isl_map *dep, int must, |
| void *dep_user, void *user), |
| void *user); |
| __isl_give isl_map *isl_flow_get_no_source( |
| __isl_keep isl_flow *deps, int must); |
| void isl_flow_free(__isl_take isl_flow *deps); |
| |
| The function C<isl_access_info_compute_flow> performs the actual |
| dependence analysis. The other functions are used to construct |
| the input for this function or to read off the output. |
| |
| The input is collected in an C<isl_access_info>, which can |
| be created through a call to C<isl_access_info_alloc>. |
| The arguments to this functions are the sink access relation |
| C<sink>, a token C<sink_user> used to identify the sink |
| access to the user, a callback function for specifying the |
| relative order of source and sink accesses, and the number |
| of source access relations that will be added. |
| |
| The callback function has type C<int (*)(void *first, void *second)>. |
| The function is called with two user supplied tokens identifying |
| either a source or the sink and it should return the shared nesting |
| level and the relative order of the two accesses. |
| In particular, let I<n> be the number of loops shared by |
| the two accesses. If C<first> precedes C<second> textually, |
| then the function should return I<2 * n + 1>; otherwise, |
| it should return I<2 * n>. |
| The low-level interface assumes that no sources are coscheduled. |
| If the information returned by the callback does not allow |
| the relative order to be determined, then one of the sources |
| is arbitrarily taken to be executed after the other(s). |
| |
| The sources can be added to the C<isl_access_info> object by performing |
| (at most) C<max_source> calls to C<isl_access_info_add_source>. |
| C<must> indicates whether the source is a I<must> access |
| or a I<may> access. Note that a multi-valued access relation |
| should only be marked I<must> if every iteration in the domain |
| of the relation accesses I<all> elements in its image. |
| The C<source_user> token is again used to identify |
| the source access. The range of the source access relation |
| C<source> should have the same dimension as the range |
| of the sink access relation. |
| The C<isl_access_info_free> function should usually not be |
| called explicitly, because it is already called implicitly by |
| C<isl_access_info_compute_flow>. |
| |
| The result of the dependence analysis is collected in an |
| C<isl_flow>. There may be elements of |
| the sink access for which no preceding source access could be |
| found or for which all preceding sources are I<may> accesses. |
| The relations containing these elements can be obtained through |
| calls to C<isl_flow_get_no_source>, the first with C<must> set |
| and the second with C<must> unset. |
| In the case of standard flow dependence analysis, |
| with the sink a read and the sources I<must> writes, |
| the first relation corresponds to the reads from uninitialized |
| array elements and the second relation is empty. |
| The actual flow dependences can be extracted using |
| C<isl_flow_foreach>. This function will call the user-specified |
| callback function C<fn> for each B<non-empty> dependence between |
| a source and the sink. The callback function is called |
| with four arguments, the actual flow dependence relation |
| mapping source iterations to sink iterations, a boolean that |
| indicates whether it is a I<must> or I<may> dependence, a token |
| identifying the source and an additional C<void *> with value |
| equal to the third argument of the C<isl_flow_foreach> call. |
| A dependence is marked I<must> if it originates from a I<must> |
| source and if it is not followed by any I<may> sources. |
| |
| After finishing with an C<isl_flow>, the user should call |
| C<isl_flow_free> to free all associated memory. |
| |
| =head3 Interaction with the Low-level Interface |
| |
| During the dependence analysis, we frequently need to perform |
| the following operation. Given a relation between sink iterations |
| and potential source iterations from a particular source domain, |
| what is the last potential source iteration corresponding to each |
| sink iteration. It can sometimes be convenient to adjust |
| the set of potential source iterations before or after each such operation. |
| The prototypical example is fuzzy array dataflow analysis, |
| where we need to analyze if, based on data-dependent constraints, |
| the sink iteration can ever be executed without one or more of |
| the corresponding potential source iterations being executed. |
| If so, we can introduce extra parameters and select an unknown |
| but fixed source iteration from the potential source iterations. |
| To be able to perform such manipulations, C<isl> provides the following |
| function. |
| |
| #include <isl/flow.h> |
| |
| typedef __isl_give isl_restriction *(*isl_access_restrict)( |
| __isl_keep isl_map *source_map, |
| __isl_keep isl_set *sink, void *source_user, |
| void *user); |
| __isl_give isl_access_info *isl_access_info_set_restrict( |
| __isl_take isl_access_info *acc, |
| isl_access_restrict fn, void *user); |
| |
| The function C<isl_access_info_set_restrict> should be called |
| before calling C<isl_access_info_compute_flow> and registers a callback function |
| that will be called any time C<isl> is about to compute the last |
| potential source. The first argument is the (reverse) proto-dependence, |
| mapping sink iterations to potential source iterations. |
| The second argument represents the sink iterations for which |
| we want to compute the last source iteration. |
| The third argument is the token corresponding to the source |
| and the final argument is the token passed to C<isl_access_info_set_restrict>. |
| The callback is expected to return a restriction on either the input or |
| the output of the operation computing the last potential source. |
| If the input needs to be restricted then restrictions are needed |
| for both the source and the sink iterations. The sink iterations |
| and the potential source iterations will be intersected with these sets. |
| If the output needs to be restricted then only a restriction on the source |
| iterations is required. |
| If any error occurs, the callback should return C<NULL>. |
| An C<isl_restriction> object can be created, freed and inspected |
| using the following functions. |
| |
| #include <isl/flow.h> |
| |
| __isl_give isl_restriction *isl_restriction_input( |
| __isl_take isl_set *source_restr, |
| __isl_take isl_set *sink_restr); |
| __isl_give isl_restriction *isl_restriction_output( |
| __isl_take isl_set *source_restr); |
| __isl_give isl_restriction *isl_restriction_none( |
| __isl_take isl_map *source_map); |
| __isl_give isl_restriction *isl_restriction_empty( |
| __isl_take isl_map *source_map); |
| __isl_null isl_restriction *isl_restriction_free( |
| __isl_take isl_restriction *restr); |
| |
| C<isl_restriction_none> and C<isl_restriction_empty> are special |
| cases of C<isl_restriction_input>. C<isl_restriction_none> |
| is essentially equivalent to |
| |
| isl_restriction_input(isl_set_universe( |
| isl_space_range(isl_map_get_space(source_map))), |
| isl_set_universe( |
| isl_space_domain(isl_map_get_space(source_map)))); |
| |
| whereas C<isl_restriction_empty> is essentially equivalent to |
| |
| isl_restriction_input(isl_set_empty( |
| isl_space_range(isl_map_get_space(source_map))), |
| isl_set_universe( |
| isl_space_domain(isl_map_get_space(source_map)))); |
| |
| =head2 Scheduling |
| |
| #include <isl/schedule.h> |
| __isl_give isl_schedule * |
| isl_schedule_constraints_compute_schedule( |
| __isl_take isl_schedule_constraints *sc); |
| |
| The function C<isl_schedule_constraints_compute_schedule> can be |
| used to compute a schedule that satisfies the given schedule constraints. |
| These schedule constraints include the iteration domain for which |
| a schedule should be computed and dependences between pairs of |
| iterations. In particular, these dependences include |
| I<validity> dependences and I<proximity> dependences. |
| By default, the algorithm used to construct the schedule is similar |
| to that of C<Pluto>. |
| Alternatively, Feautrier's multi-dimensional scheduling algorithm can |
| be selected. |
| The generated schedule respects all validity dependences. |
| That is, all dependence distances over these dependences in the |
| scheduled space are lexicographically positive. |
| |
| The default algorithm tries to ensure that the dependence distances |
| over coincidence constraints are zero and to minimize the |
| dependence distances over proximity dependences. |
| Moreover, it tries to obtain sequences (bands) of schedule dimensions |
| for groups of domains where the dependence distances over validity |
| dependences have only non-negative values. |
| Note that when minimizing the maximal dependence distance |
| over proximity dependences, a single affine expression in the parameters |
| is constructed that bounds all dependence distances. If no such expression |
| exists, then the algorithm will fail and resort to an alternative |
| scheduling algorithm. In particular, this means that adding proximity |
| dependences may eliminate valid solutions. A typical example where this |
| phenomenon may occur is when some subset of the proximity dependences |
| has no restriction on some parameter, forcing the coefficient of that |
| parameter to be zero, while some other subset forces the dependence |
| distance to depend on that parameter, requiring the same coefficient |
| to be non-zero. |
| When using Feautrier's algorithm, the coincidence and proximity constraints |
| are only taken into account during the extension to a |
| full-dimensional schedule. |
| |
| An C<isl_schedule_constraints> object can be constructed |
| and manipulated using the following functions. |
| |
| #include <isl/schedule.h> |
| __isl_give isl_schedule_constraints * |
| isl_schedule_constraints_copy( |
| __isl_keep isl_schedule_constraints *sc); |
| __isl_give isl_schedule_constraints * |
| isl_schedule_constraints_on_domain( |
| __isl_take isl_union_set *domain); |
| __isl_give isl_schedule_constraints * |
| isl_schedule_constraints_set_context( |
| __isl_take isl_schedule_constraints *sc, |
| __isl_take isl_set *context); |
| __isl_give isl_schedule_constraints * |
| isl_schedule_constraints_set_validity( |
| __isl_take isl_schedule_constraints *sc, |
| __isl_take isl_union_map *validity); |
| __isl_give isl_schedule_constraints * |
| isl_schedule_constraints_set_coincidence( |
| __isl_take isl_schedule_constraints *sc, |
| __isl_take isl_union_map *coincidence); |
| __isl_give isl_schedule_constraints * |
| isl_schedule_constraints_set_proximity( |
| __isl_take isl_schedule_constraints *sc, |
| __isl_take isl_union_map *proximity); |
| __isl_give isl_schedule_constraints * |
| isl_schedule_constraints_set_conditional_validity( |
| __isl_take isl_schedule_constraints *sc, |
| __isl_take isl_union_map *condition, |
| __isl_take isl_union_map *validity); |
| __isl_give isl_schedule_constraints * |
| isl_schedule_constraints_apply( |
| __isl_take isl_schedule_constraints *sc, |
| __isl_take isl_union_map *umap); |
| __isl_null isl_schedule_constraints * |
| isl_schedule_constraints_free( |
| __isl_take isl_schedule_constraints *sc); |
| |
| The initial C<isl_schedule_constraints> object created by |
| C<isl_schedule_constraints_on_domain> does not impose any constraints. |
| That is, it has an empty set of dependences. |
| The function C<isl_schedule_constraints_set_context> allows the user |
| to specify additional constraints on the parameters that may |
| be assumed to hold during the construction of the schedule. |
| The function C<isl_schedule_constraints_set_validity> replaces the |
| validity dependences, mapping domain elements I<i> to domain |
| elements that should be scheduled after I<i>. |
| The function C<isl_schedule_constraints_set_coincidence> replaces the |
| coincidence dependences, mapping domain elements I<i> to domain |
| elements that should be scheduled together with I<I>, if possible. |
| The function C<isl_schedule_constraints_set_proximity> replaces the |
| proximity dependences, mapping domain elements I<i> to domain |
| elements that should be scheduled either before I<I> |
| or as early as possible after I<i>. |
| |
| The function C<isl_schedule_constraints_set_conditional_validity> |
| replaces the conditional validity constraints. |
| A conditional validity constraint is only imposed when any of the corresponding |
| conditions is satisfied, i.e., when any of them is non-zero. |
| That is, the scheduler ensures that within each band if the dependence |
| distances over the condition constraints are not all zero |
| then all corresponding conditional validity constraints are respected. |
| A conditional validity constraint corresponds to a condition |
| if the two are adjacent, i.e., if the domain of one relation intersect |
| the range of the other relation. |
| The typical use case of conditional validity constraints is |
| to allow order constraints between live ranges to be violated |
| as long as the live ranges themselves are local to the band. |
| To allow more fine-grained control over which conditions correspond |
| to which conditional validity constraints, the domains and ranges |
| of these relations may include I<tags>. That is, the domains and |
| ranges of those relation may themselves be wrapped relations |
| where the iteration domain appears in the domain of those wrapped relations |
| and the range of the wrapped relations can be arbitrarily chosen |
| by the user. Conditions and conditional validity constraints are only |
| considered adjacent to each other if the entire wrapped relation matches. |
| In particular, a relation with a tag will never be considered adjacent |
| to a relation without a tag. |
| |
| The function C<isl_schedule_constraints_apply> takes |
| schedule constraints that are defined on some set of domain elements |
| and transforms them to schedule constraints on the elements |
| to which these domain elements are mapped by the given transformation. |
| |
| An C<isl_schedule_constraints> object can be inspected |
| using the following functions. |
| |
| #include <isl/schedule.h> |
| __isl_give isl_union_set * |
| isl_schedule_constraints_get_domain( |
| __isl_keep isl_schedule_constraints *sc); |
| __isl_give isl_set *isl_schedule_constraints_get_context( |
| __isl_keep isl_schedule_constraints *sc); |
| __isl_give isl_union_map * |
| isl_schedule_constraints_get_validity( |
| __isl_keep isl_schedule_constraints *sc); |
| __isl_give isl_union_map * |
| isl_schedule_constraints_get_coincidence( |
| __isl_keep isl_schedule_constraints *sc); |
| __isl_give isl_union_map * |
| isl_schedule_constraints_get_proximity( |
| __isl_keep isl_schedule_constraints *sc); |
| __isl_give isl_union_map * |
| isl_schedule_constraints_get_conditional_validity( |
| __isl_keep isl_schedule_constraints *sc); |
| __isl_give isl_union_map * |
| isl_schedule_constraints_get_conditional_validity_condition( |
| __isl_keep isl_schedule_constraints *sc); |
| |
| An C<isl_schedule_constraints> object can be read from input |
| using the following functions. |
| |
| #include <isl/schedule.h> |
| __isl_give isl_schedule_constraints * |
| isl_schedule_constraints_read_from_str(isl_ctx *ctx, |
| const char *str); |
| __isl_give isl_schedule_constraints * |
| isl_schedule_constraints_read_from_file(isl_ctx *ctx, |
| FILE *input); |
| |
| The contents of an C<isl_schedule_constraints> object can be printed |
| using the following functions. |
| |
| #include <isl/schedule.h> |
| __isl_give isl_printer * |
| isl_printer_print_schedule_constraints( |
| __isl_take isl_printer *p, |
| __isl_keep isl_schedule_constraints *sc); |
| __isl_give char *isl_schedule_constraints_to_str( |
| __isl_keep isl_schedule_constraints *sc); |
| |
| The following function computes a schedule directly from |
| an iteration domain and validity and proximity dependences |
| and is implemented in terms of the functions described above. |
| The use of C<isl_union_set_compute_schedule> is discouraged. |
| |
| #include <isl/schedule.h> |
| __isl_give isl_schedule *isl_union_set_compute_schedule( |
| __isl_take isl_union_set *domain, |
| __isl_take isl_union_map *validity, |
| __isl_take isl_union_map *proximity); |
| |
| The generated schedule represents a schedule tree. |
| For more information on schedule trees, see |
| L</"Schedule Trees">. |
| |
| =head3 Options |
| |
| #include <isl/schedule.h> |
| isl_stat isl_options_set_schedule_max_coefficient( |
| isl_ctx *ctx, int val); |
| int isl_options_get_schedule_max_coefficient( |
| isl_ctx *ctx); |
| isl_stat isl_options_set_schedule_max_constant_term( |
| isl_ctx *ctx, int val); |
| int isl_options_get_schedule_max_constant_term( |
| isl_ctx *ctx); |
| isl_stat isl_options_set_schedule_serialize_sccs( |
| isl_ctx *ctx, int val); |
| int isl_options_get_schedule_serialize_sccs(isl_ctx *ctx); |
| isl_stat isl_options_set_schedule_whole_component( |
| isl_ctx *ctx, int val); |
| int isl_options_get_schedule_whole_component( |
| isl_ctx *ctx); |
| isl_stat isl_options_set_schedule_maximize_band_depth( |
| isl_ctx *ctx, int val); |
| int isl_options_get_schedule_maximize_band_depth( |
| isl_ctx *ctx); |
| isl_stat isl_options_set_schedule_maximize_coincidence( |
| isl_ctx *ctx, int val); |
| int isl_options_get_schedule_maximize_coincidence( |
| isl_ctx *ctx); |
| isl_stat isl_options_set_schedule_outer_coincidence( |
| isl_ctx *ctx, int val); |
| int isl_options_get_schedule_outer_coincidence( |
| isl_ctx *ctx); |
| isl_stat isl_options_set_schedule_split_scaled( |
| isl_ctx *ctx, int val); |
| int isl_options_get_schedule_split_scaled( |
| isl_ctx *ctx); |
| isl_stat isl_options_set_schedule_treat_coalescing( |
| isl_ctx *ctx, int val); |
| int isl_options_get_schedule_treat_coalescing( |
| isl_ctx *ctx); |
| isl_stat isl_options_set_schedule_algorithm( |
| isl_ctx *ctx, int val); |
| int isl_options_get_schedule_algorithm( |
| isl_ctx *ctx); |
| isl_stat isl_options_set_schedule_carry_self_first( |
| isl_ctx *ctx, int val); |
| int isl_options_get_schedule_carry_self_first( |
| isl_ctx *ctx); |
| isl_stat isl_options_set_schedule_separate_components( |
| isl_ctx *ctx, int val); |
| int isl_options_get_schedule_separate_components( |
| isl_ctx *ctx); |
| |
| =over |
| |
| =item * schedule_max_coefficient |
| |
| This option enforces that the coefficients for variable and parameter |
| dimensions in the calculated schedule are not larger than the specified value. |
| This option can significantly increase the speed of the scheduling calculation |
| and may also prevent fusing of unrelated dimensions. A value of -1 means that |
| this option does not introduce bounds on the variable or parameter |
| coefficients. |
| This option has no effect on the Feautrier style scheduler. |
| |
| =item * schedule_max_constant_term |
| |
| This option enforces that the constant coefficients in the calculated schedule |
| are not larger than the maximal constant term. This option can significantly |
| increase the speed of the scheduling calculation and may also prevent fusing of |
| unrelated dimensions. A value of -1 means that this option does not introduce |
| bounds on the constant coefficients. |
| |
| =item * schedule_serialize_sccs |
| |
| If this option is set, then all strongly connected components |
| in the dependence graph are serialized as soon as they are detected. |
| This means in particular that instances of statements will only |
| appear in the same band node if these statements belong |
| to the same strongly connected component at the point where |
| the band node is constructed. |
| |
| =item * schedule_whole_component |
| |
| If this option is set, then entire (weakly) connected |
| components in the dependence graph are scheduled together |
| as a whole. |
| Otherwise, each strongly connected component within |
| such a weakly connected component is first scheduled separately |
| and then combined with other strongly connected components. |
| This option has no effect if C<schedule_serialize_sccs> is set. |
| |
| =item * schedule_maximize_band_depth |
| |
| If this option is set, then the scheduler tries to maximize |
| the width of the bands. Wider bands give more possibilities for tiling. |
| In particular, if the C<schedule_whole_component> option is set, |
| then bands are split if this might result in wider bands. |
| Otherwise, the effect of this option is to only allow |
| strongly connected components to be combined if this does |
| not reduce the width of the bands. |
| Note that if the C<schedule_serialize_sccs> options is set, then |
| the C<schedule_maximize_band_depth> option therefore has no effect. |
| |
| =item * schedule_maximize_coincidence |
| |
| This option is only effective if the C<schedule_whole_component> |
| option is turned off. |
| If the C<schedule_maximize_coincidence> option is set, then (clusters of) |
| strongly connected components are only combined with each other |
| if this does not reduce the number of coincident band members. |
| |
| =item * schedule_outer_coincidence |
| |
| If this option is set, then we try to construct schedules |
| where the outermost scheduling dimension in each band |
| satisfies the coincidence constraints. |
| |
| =item * schedule_algorithm |
| |
| Selects the scheduling algorithm to be used. |
| Available scheduling algorithms are C<ISL_SCHEDULE_ALGORITHM_ISL> |
| and C<ISL_SCHEDULE_ALGORITHM_FEAUTRIER>. |
| |
| =item * schedule_split_scaled |
| |
| If this option is set, then we try to construct schedules in which the |
| constant term is split off from the linear part if the linear parts of |
| the scheduling rows for all nodes in the graph have a common non-trivial |
| divisor. |
| The constant term is then dropped and the linear |
| part is reduced. |
| This option is only effective when the Feautrier style scheduler is |
| being used, either as the main scheduler or as a fallback for the |
| Pluto-like scheduler. |
| |
| =item * schedule_treat_coalescing |
| |
| If this option is set, then the scheduler will try and avoid |
| producing schedules that perform loop coalescing. |
| In particular, for the Pluto-like scheduler, this option places |
| bounds on the schedule coefficients based on the sizes of the instance sets. |
| For the Feautrier style scheduler, this option detects potentially |
| coalescing schedules and then tries to adjust the schedule to avoid |
| the coalescing. |
| |
| =item * schedule_carry_self_first |
| |
| If this option is set, then the Feautrier style scheduler |
| (when used as a fallback for the Pluto-like scheduler) will |
| first try to only carry self-dependences. |
| |
| =item * schedule_separate_components |
| |
| If this option is set then the function C<isl_schedule_get_map> |
| will treat set nodes in the same way as sequence nodes. |
| |
| =back |
| |
| =head2 AST Generation |
| |
| This section describes the C<isl> functionality for generating |
| ASTs that visit all the elements |
| in a domain in an order specified by a schedule tree or |
| a schedule map. |
| In case the schedule given as a C<isl_union_map>, an AST is generated |
| that visits all the elements in the domain of the C<isl_union_map> |
| according to the lexicographic order of the corresponding image |
| element(s). If the range of the C<isl_union_map> consists of |
| elements in more than one space, then each of these spaces is handled |
| separately in an arbitrary order. |
| It should be noted that the schedule tree or the image elements |
| in a schedule map only specify the I<order> |
| in which the corresponding domain elements should be visited. |
| No direct relation between the partial schedule values |
| or the image elements on the one hand and the loop iterators |
| in the generated AST on the other hand should be assumed. |
| |
| Each AST is generated within a build. The initial build |
| simply specifies the constraints on the parameters (if any) |
| and can be created, inspected, copied and freed using the following functions. |
| |
| #include <isl/ast_build.h> |
| __isl_give isl_ast_build *isl_ast_build_alloc( |
| isl_ctx *ctx); |
| __isl_give isl_ast_build *isl_ast_build_from_context( |
| __isl_take isl_set *set); |
| __isl_give isl_ast_build *isl_ast_build_copy( |
| __isl_keep isl_ast_build *build); |
| __isl_null isl_ast_build *isl_ast_build_free( |
| __isl_take isl_ast_build *build); |
| |
| The C<set> argument is usually a parameter set with zero or more parameters. |
| In fact, when creating an AST using C<isl_ast_build_node_from_schedule>, |
| this set is required to be a parameter set. |
| An C<isl_ast_build> created using C<isl_ast_build_alloc> does not |
| specify any parameter constraints. |
| More C<isl_ast_build> functions are described in L</"Nested AST Generation"> |
| and L</"Fine-grained Control over AST Generation">. |
| Finally, the AST itself can be constructed using one of the following |
| functions. |
| |
| #include <isl/ast_build.h> |
| __isl_give isl_ast_node *isl_ast_build_node_from_schedule( |
| __isl_keep isl_ast_build *build, |
| __isl_take isl_schedule *schedule); |
| __isl_give isl_ast_node * |
| isl_ast_build_node_from_schedule_map( |
| __isl_keep isl_ast_build *build, |
| __isl_take isl_union_map *schedule); |
| |
| =head3 Inspecting the AST |
| |
| The basic properties of an AST node can be obtained as follows. |
| |
| #include <isl/ast.h> |
| enum isl_ast_node_type isl_ast_node_get_type( |
| __isl_keep isl_ast_node *node); |
| |
| The type of an AST node is one of |
| C<isl_ast_node_for>, |
| C<isl_ast_node_if>, |
| C<isl_ast_node_block>, |
| C<isl_ast_node_mark> or |
| C<isl_ast_node_user>. |
| An C<isl_ast_node_for> represents a for node. |
| An C<isl_ast_node_if> represents an if node. |
| An C<isl_ast_node_block> represents a compound node. |
| An C<isl_ast_node_mark> introduces a mark in the AST. |
| An C<isl_ast_node_user> represents an expression statement. |
| An expression statement typically corresponds to a domain element, i.e., |
| one of the elements that is visited by the AST. |
| |
| Each type of node has its own additional properties. |
| |
| #include <isl/ast.h> |
| __isl_give isl_ast_expr *isl_ast_node_for_get_iterator( |
| __isl_keep isl_ast_node *node); |
| __isl_give isl_ast_expr *isl_ast_node_for_get_init( |
| __isl_keep isl_ast_node *node); |
| __isl_give isl_ast_expr *isl_ast_node_for_get_cond( |
| __isl_keep isl_ast_node *node); |
| __isl_give isl_ast_expr *isl_ast_node_for_get_inc( |
| __isl_keep isl_ast_node *node); |
| __isl_give isl_ast_node *isl_ast_node_for_get_body( |
| __isl_keep isl_ast_node *node); |
| isl_bool isl_ast_node_for_is_degenerate( |
| __isl_keep isl_ast_node *node); |
| |
| An C<isl_ast_for> is considered degenerate if it is known to execute |
| exactly once. |
| |
| #include <isl/ast.h> |
| __isl_give isl_ast_expr *isl_ast_node_if_get_cond( |
| __isl_keep isl_ast_node *node); |
| __isl_give isl_ast_node *isl_ast_node_if_get_then( |
| __isl_keep isl_ast_node *node); |
| isl_bool isl_ast_node_if_has_else( |
| __isl_keep isl_ast_node *node); |
| __isl_give isl_ast_node *isl_ast_node_if_get_else( |
| __isl_keep isl_ast_node *node); |
| |
| __isl_give isl_ast_node_list * |
| isl_ast_node_block_get_children( |
| __isl_keep isl_ast_node *node); |
| |
| __isl_give isl_id *isl_ast_node_mark_get_id( |
| __isl_keep isl_ast_node *node); |
| __isl_give isl_ast_node *isl_ast_node_mark_get_node( |
| __isl_keep isl_ast_node *node); |
| |
| C<isl_ast_node_mark_get_id> returns the identifier of the mark. |
| C<isl_ast_node_mark_get_node> returns the child node that is being marked. |
| |
| #include <isl/ast.h> |
| __isl_give isl_ast_expr *isl_ast_node_user_get_expr( |
| __isl_keep isl_ast_node *node); |
| |
| All descendants of a specific node in the AST (including the node itself) |
| can be visited |
| in depth-first pre-order using the following function. |
| |
| #include <isl/ast.h> |
| isl_stat isl_ast_node_foreach_descendant_top_down( |
| __isl_keep isl_ast_node *node, |
| isl_bool (*fn)(__isl_keep isl_ast_node *node, |
| void *user), void *user); |
| |
| The callback function should return C<isl_bool_true> if the children |
| of the given node should be visited and C<isl_bool_false> if they should not. |
| It should return C<isl_bool_error> in case of failure, in which case |
| the entire traversal is aborted. |
| |
| Each of the returned C<isl_ast_expr>s can in turn be inspected using |
| the following functions. |
| |
| #include <isl/ast.h> |
| enum isl_ast_expr_type isl_ast_expr_get_type( |
| __isl_keep isl_ast_expr *expr); |
| |
| The type of an AST expression is one of |
| C<isl_ast_expr_op>, |
| C<isl_ast_expr_id> or |
| C<isl_ast_expr_int>. |
| An C<isl_ast_expr_op> represents the result of an operation. |
| An C<isl_ast_expr_id> represents an identifier. |
| An C<isl_ast_expr_int> represents an integer value. |
| |
| Each type of expression has its own additional properties. |
| |
| #include <isl/ast.h> |
| enum isl_ast_op_type isl_ast_expr_get_op_type( |
| __isl_keep isl_ast_expr *expr); |
| int isl_ast_expr_get_op_n_arg(__isl_keep isl_ast_expr *expr); |
| __isl_give isl_ast_expr *isl_ast_expr_get_op_arg( |
| __isl_keep isl_ast_expr *expr, int pos); |
| isl_stat isl_ast_expr_foreach_ast_op_type( |
| __isl_keep isl_ast_expr *expr, |
| isl_stat (*fn)(enum isl_ast_op_type type, |
| void *user), void *user); |
| isl_stat isl_ast_node_foreach_ast_op_type( |
| __isl_keep isl_ast_node *node, |
| isl_stat (*fn)(enum isl_ast_op_type type, |
| void *user), void *user); |
| |
| C<isl_ast_expr_get_op_type> returns the type of the operation |
| performed. C<isl_ast_expr_get_op_n_arg> returns the number of |
| arguments. C<isl_ast_expr_get_op_arg> returns the specified |
| argument. |
| C<isl_ast_expr_foreach_ast_op_type> calls C<fn> for each distinct |
| C<isl_ast_op_type> that appears in C<expr>. |
| C<isl_ast_node_foreach_ast_op_type> does the same for each distinct |
| C<isl_ast_op_type> that appears in C<node>. |
| The operation type is one of the following. |
| |
| =over |
| |
| =item C<isl_ast_op_and> |
| |
| Logical I<and> of two arguments. |
| Both arguments can be evaluated. |
| |
| =item C<isl_ast_op_and_then> |
| |
| Logical I<and> of two arguments. |
| The second argument can only be evaluated if the first evaluates to true. |
| |
| =item C<isl_ast_op_or> |
| |
| Logical I<or> of two arguments. |
| Both arguments can be evaluated. |
| |
| =item C<isl_ast_op_or_else> |
| |
| Logical I<or> of two arguments. |
| The second argument can only be evaluated if the first evaluates to false. |
| |
| =item C<isl_ast_op_max> |
| |
| Maximum of two or more arguments. |
| |
| =item C<isl_ast_op_min> |
| |
| Minimum of two or more arguments. |
| |
| =item C<isl_ast_op_minus> |
| |
| Change sign. |
| |
| =item C<isl_ast_op_add> |
| |
| Sum of two arguments. |
| |
| =item C<isl_ast_op_sub> |
| |
| Difference of two arguments. |
| |
| =item C<isl_ast_op_mul> |
| |
| Product of two arguments. |
| |
| =item C<isl_ast_op_div> |
| |
| Exact division. That is, the result is known to be an integer. |
| |
| =item C<isl_ast_op_fdiv_q> |
| |
| Result of integer division, rounded towards negative |
| infinity. |
| The divisor is known to be positive. |
| |
| =item C<isl_ast_op_pdiv_q> |
| |
| Result of integer division, where dividend is known to be non-negative. |
| The divisor is known to be positive. |
| |
| =item C<isl_ast_op_pdiv_r> |
| |
| Remainder of integer division, where dividend is known to be non-negative. |
| The divisor is known to be positive. |
| |
| =item C<isl_ast_op_zdiv_r> |
| |
| Equal to zero iff the remainder on integer division is zero. |
| The divisor is known to be positive. |
| |
| =item C<isl_ast_op_cond> |
| |
| Conditional operator defined on three arguments. |
| If the first argument evaluates to true, then the result |
| is equal to the second argument. Otherwise, the result |
| is equal to the third argument. |
| The second and third argument may only be evaluated if |
| the first argument evaluates to true and false, respectively. |
| Corresponds to C<a ? b : c> in C. |
| |
| =item C<isl_ast_op_select> |
| |
| Conditional operator defined on three arguments. |
| If the first argument evaluates to true, then the result |
| is equal to the second argument. Otherwise, the result |
| is equal to the third argument. |
| The second and third argument may be evaluated independently |
| of the value of the first argument. |
| Corresponds to C<a * b + (1 - a) * c> in C. |
| |
| =item C<isl_ast_op_eq> |
| |
| Equality relation. |
| |
| =item C<isl_ast_op_le> |
| |
| Less than or equal relation. |
| |
| =item C<isl_ast_op_lt> |
| |
| Less than relation. |
| |
| =item C<isl_ast_op_ge> |
| |
| Greater than or equal relation. |
| |
| =item C<isl_ast_op_gt> |
| |
| Greater than relation. |
| |
| =item C<isl_ast_op_call> |
| |
| A function call. |
| The number of arguments of the C<isl_ast_expr> is one more than |
| the number of arguments in the function call, the first argument |
| representing the function being called. |
| |
| =item C<isl_ast_op_access> |
| |
| An array access. |
| The number of arguments of the C<isl_ast_expr> is one more than |
| the number of index expressions in the array access, the first argument |
| representing the array being accessed. |
| |
| =item C<isl_ast_op_member> |
| |
| A member access. |
| This operation has two arguments, a structure and the name of |
| the member of the structure being accessed. |
| |
| =back |
| |
| #include <isl/ast.h> |
| __isl_give isl_id *isl_ast_expr_get_id( |
| __isl_keep isl_ast_expr *expr); |
| |
| Return the identifier represented by the AST expression. |
| |
| #include <isl/ast.h> |
| __isl_give isl_val *isl_ast_expr_get_val( |
| __isl_keep isl_ast_expr *expr); |
| |
| Return the integer represented by the AST expression. |
| |
| =head3 Properties of ASTs |
| |
| #include <isl/ast.h> |
| isl_bool isl_ast_expr_is_equal( |
| __isl_keep isl_ast_expr *expr1, |
| __isl_keep isl_ast_expr *expr2); |
| |
| Check if two C<isl_ast_expr>s are equal to each other. |
| |
| =head3 Manipulating and printing the AST |
| |
| AST nodes can be copied and freed using the following functions. |
| |
| #include <isl/ast.h> |
| __isl_give isl_ast_node *isl_ast_node_copy( |
| __isl_keep isl_ast_node *node); |
| __isl_null isl_ast_node *isl_ast_node_free( |
| __isl_take isl_ast_node *node); |
| |
| AST expressions can be copied and freed using the following functions. |
| |
| #include <isl/ast.h> |
| __isl_give isl_ast_expr *isl_ast_expr_copy( |
| __isl_keep isl_ast_expr *expr); |
| __isl_null isl_ast_expr *isl_ast_expr_free( |
| __isl_take isl_ast_expr *expr); |
| |
| New AST expressions can be created either directly or within |
| the context of an C<isl_ast_build>. |
| |
| #include <isl/ast.h> |
| __isl_give isl_ast_expr *isl_ast_expr_from_val( |
| __isl_take isl_val *v); |
| __isl_give isl_ast_expr *isl_ast_expr_from_id( |
| __isl_take isl_id *id); |
| __isl_give isl_ast_expr *isl_ast_expr_neg( |
| __isl_take isl_ast_expr *expr); |
| __isl_give isl_ast_expr *isl_ast_expr_address_of( |
| __isl_take isl_ast_expr *expr); |
| __isl_give isl_ast_expr *isl_ast_expr_add( |
| __isl_take isl_ast_expr *expr1, |
| __isl_take isl_ast_expr *expr2); |
| __isl_give isl_ast_expr *isl_ast_expr_sub( |
| __isl_take isl_ast_expr *expr1, |
| __isl_take isl_ast_expr *expr2); |
| __isl_give isl_ast_expr *isl_ast_expr_mul( |
| __isl_take isl_ast_expr *expr1, |
| __isl_take isl_ast_expr *expr2); |
| __isl_give isl_ast_expr *isl_ast_expr_div( |
| __isl_take isl_ast_expr *expr1, |
| __isl_take isl_ast_expr *expr2); |
| __isl_give isl_ast_expr *isl_ast_expr_pdiv_q( |
| __isl_take isl_ast_expr *expr1, |
| __isl_take isl_ast_expr *expr2); |
| __isl_give isl_ast_expr *isl_ast_expr_pdiv_r( |
| __isl_take isl_ast_expr *expr1, |
| __isl_take isl_ast_expr *expr2); |
| __isl_give isl_ast_expr *isl_ast_expr_and( |
| __isl_take isl_ast_expr *expr1, |
| __isl_take isl_ast_expr *expr2) |
| __isl_give isl_ast_expr *isl_ast_expr_and_then( |
| __isl_take isl_ast_expr *expr1, |
| __isl_take isl_ast_expr *expr2) |
| __isl_give isl_ast_expr *isl_ast_expr_or( |
| __isl_take isl_ast_expr *expr1, |
| __isl_take isl_ast_expr *expr2) |
| __isl_give isl_ast_expr *isl_ast_expr_or_else( |
| __isl_take isl_ast_expr *expr1, |
| __isl_take isl_ast_expr *expr2) |
| __isl_give isl_ast_expr *isl_ast_expr_eq( |
| __isl_take isl_ast_expr *expr1, |
| __isl_take isl_ast_expr *expr2); |
| __isl_give isl_ast_expr *isl_ast_expr_le( |
| __isl_take isl_ast_expr *expr1, |
| __isl_take isl_ast_expr *expr2); |
| __isl_give isl_ast_expr *isl_ast_expr_lt( |
| __isl_take isl_ast_expr *expr1, |
| __isl_take isl_ast_expr *expr2); |
| __isl_give isl_ast_expr *isl_ast_expr_ge( |
| __isl_take isl_ast_expr *expr1, |
| __isl_take isl_ast_expr *expr2); |
| __isl_give isl_ast_expr *isl_ast_expr_gt( |
| __isl_take isl_ast_expr *expr1, |
| __isl_take isl_ast_expr *expr2); |
| __isl_give isl_ast_expr *isl_ast_expr_access( |
| __isl_take isl_ast_expr *array, |
| __isl_take isl_ast_expr_list *indices); |
| __isl_give isl_ast_expr *isl_ast_expr_call( |
| __isl_take isl_ast_expr *function, |
| __isl_take isl_ast_expr_list *arguments); |
| |
| The function C<isl_ast_expr_address_of> can be applied to an |
| C<isl_ast_expr> of type C<isl_ast_op_access> only. It is meant |
| to represent the address of the C<isl_ast_expr_access>. |
| The second argument of the functions C<isl_ast_expr_pdiv_q> and |
| C<isl_ast_expr_pdiv_r> should always evaluate to a positive number. |
| The function |
| C<isl_ast_expr_and_then> as well as C<isl_ast_expr_or_else> are short-circuit |
| versions of C<isl_ast_expr_and> and C<isl_ast_expr_or>, respectively. |
| |
| #include <isl/ast_build.h> |
| __isl_give isl_ast_expr *isl_ast_build_expr_from_set( |
| __isl_keep isl_ast_build *build, |
| __isl_take isl_set *set); |
| __isl_give isl_ast_expr *isl_ast_build_expr_from_pw_aff( |
| __isl_keep isl_ast_build *build, |
| __isl_take isl_pw_aff *pa); |
| __isl_give isl_ast_expr * |
| isl_ast_build_access_from_pw_multi_aff( |
| __isl_keep isl_ast_build *build, |
| __isl_take isl_pw_multi_aff *pma); |
| __isl_give isl_ast_expr * |
| isl_ast_build_access_from_multi_pw_aff( |
| __isl_keep isl_ast_build *build, |
| __isl_take isl_multi_pw_aff *mpa); |
| __isl_give isl_ast_expr * |
| isl_ast_build_call_from_pw_multi_aff( |
| __isl_keep isl_ast_build *build, |
| __isl_take isl_pw_multi_aff *pma); |
| __isl_give isl_ast_expr * |
| isl_ast_build_call_from_multi_pw_aff( |
| __isl_keep isl_ast_build *build, |
| __isl_take isl_multi_pw_aff *mpa); |
| |
| The set C<set> and |
| the domains of C<pa>, C<mpa> and C<pma> should correspond |
| to the schedule space of C<build>. |
| The tuple id of C<mpa> or C<pma> is used as the array being accessed or |
| the function being called. |
| If the accessed space is a nested relation, then it is taken |
| to represent an access of the member specified by the range |
| of this nested relation of the structure specified by the domain |
| of the nested relation. |
| |
| The following functions can be used to modify an C<isl_ast_expr>. |
| |
| #include <isl/ast.h> |
| __isl_give isl_ast_expr *isl_ast_expr_set_op_arg( |
| __isl_take isl_ast_expr *expr, int pos, |
| __isl_take isl_ast_expr *arg); |
| |
| Replace the argument of C<expr> at position C<pos> by C<arg>. |
| |
| #include <isl/ast.h> |
| __isl_give isl_ast_expr *isl_ast_expr_substitute_ids( |
| __isl_take isl_ast_expr *expr, |
| __isl_take isl_id_to_ast_expr *id2expr); |
| |
| The function C<isl_ast_expr_substitute_ids> replaces the |
| subexpressions of C<expr> of type C<isl_ast_expr_id> |
| by the corresponding expression in C<id2expr>, if there is any. |
| |
| |
| User specified data can be attached to an C<isl_ast_node> and obtained |
| from the same C<isl_ast_node> using the following functions. |
| |
| #include <isl/ast.h> |
| __isl_give isl_ast_node *isl_ast_node_set_annotation( |
| __isl_take isl_ast_node *node, |
| __isl_take isl_id *annotation); |
| __isl_give isl_id *isl_ast_node_get_annotation( |
| __isl_keep isl_ast_node *node); |
| |
| Basic printing can be performed using the following functions. |
| |
| #include <isl/ast.h> |
| __isl_give isl_printer *isl_printer_print_ast_expr( |
| __isl_take isl_printer *p, |
| __isl_keep isl_ast_expr *expr); |
| __isl_give isl_printer *isl_printer_print_ast_node( |
| __isl_take isl_printer *p, |
| __isl_keep isl_ast_node *node); |
| __isl_give char *isl_ast_expr_to_str( |
| __isl_keep isl_ast_expr *expr); |
| __isl_give char *isl_ast_node_to_str( |
| __isl_keep isl_ast_node *node); |
| __isl_give char *isl_ast_expr_to_C_str( |
| __isl_keep isl_ast_expr *expr); |
| __isl_give char *isl_ast_node_to_C_str( |
| __isl_keep isl_ast_node *node); |
| |
| The functions C<isl_ast_expr_to_C_str> and |
| C<isl_ast_node_to_C_str> are convenience functions |
| that return a string representation of the input in C format. |
| |
| More advanced printing can be performed using the following functions. |
| |
| #include <isl/ast.h> |
| __isl_give isl_printer *isl_ast_op_type_set_print_name( |
| __isl_take isl_printer *p, |
| enum isl_ast_op_type type, |
| __isl_keep const char *name); |
| isl_stat isl_options_set_ast_print_macro_once( |
| isl_ctx *ctx, int val); |
| int isl_options_get_ast_print_macro_once(isl_ctx *ctx); |
| __isl_give isl_printer *isl_ast_op_type_print_macro( |
| enum isl_ast_op_type type, |
| __isl_take isl_printer *p); |
| __isl_give isl_printer *isl_ast_expr_print_macros( |
| __isl_keep isl_ast_expr *expr, |
| __isl_take isl_printer *p); |
| __isl_give isl_printer *isl_ast_node_print_macros( |
| __isl_keep isl_ast_node *node, |
| __isl_take isl_printer *p); |
| __isl_give isl_printer *isl_ast_node_print( |
| __isl_keep isl_ast_node *node, |
| __isl_take isl_printer *p, |
| __isl_take isl_ast_print_options *options); |
| __isl_give isl_printer *isl_ast_node_for_print( |
| __isl_keep isl_ast_node *node, |
| __isl_take isl_printer *p, |
| __isl_take isl_ast_print_options *options); |
| __isl_give isl_printer *isl_ast_node_if_print( |
| __isl_keep isl_ast_node *node, |
| __isl_take isl_printer *p, |
| __isl_take isl_ast_print_options *options); |
| |
| While printing an C<isl_ast_node> in C<ISL_FORMAT_C>, |
| C<isl> may print out an AST that makes use of macros such |
| as C<floord>, C<min> and C<max>. |
| The names of these macros may be modified by a call |
| to C<isl_ast_op_type_set_print_name>. The user-specified |
| names are associated to the printer object. |
| C<isl_ast_op_type_print_macro> prints out the macro |
| corresponding to a specific C<isl_ast_op_type>. |
| If the print-macro-once option is set, then a given macro definition |
| is only printed once to any given printer object. |
| C<isl_ast_expr_print_macros> scans the C<isl_ast_expr> |
| for subexpressions where these macros would be used and prints |
| out the required macro definitions. |
| Essentially, C<isl_ast_expr_print_macros> calls |
| C<isl_ast_expr_foreach_ast_op_type> with C<isl_ast_op_type_print_macro> |
| as function argument. |
| C<isl_ast_node_print_macros> does the same |
| for expressions in its C<isl_ast_node> argument. |
| C<isl_ast_node_print>, C<isl_ast_node_for_print> and |
| C<isl_ast_node_if_print> print an C<isl_ast_node> |
| in C<ISL_FORMAT_C>, but allow for some extra control |
| through an C<isl_ast_print_options> object. |
| This object can be created using the following functions. |
| |
| #include <isl/ast.h> |
| __isl_give isl_ast_print_options * |
| isl_ast_print_options_alloc(isl_ctx *ctx); |
| __isl_give isl_ast_print_options * |
| isl_ast_print_options_copy( |
| __isl_keep isl_ast_print_options *options); |
| __isl_null isl_ast_print_options * |
| isl_ast_print_options_free( |
| __isl_take isl_ast_print_options *options); |
| |
| __isl_give isl_ast_print_options * |
| isl_ast_print_options_set_print_user( |
| __isl_take isl_ast_print_options *options, |
| __isl_give isl_printer *(*print_user)( |
| __isl_take isl_printer *p, |
| __isl_take isl_ast_print_options *options, |
| __isl_keep isl_ast_node *node, void *user), |
| void *user); |
| __isl_give isl_ast_print_options * |
| isl_ast_print_options_set_print_for( |
| __isl_take isl_ast_print_options *options, |
| __isl_give isl_printer *(*print_for)( |
| __isl_take isl_printer *p, |
| __isl_take isl_ast_print_options *options, |
| __isl_keep isl_ast_node *node, void *user), |
| void *user); |
| |
| The callback set by C<isl_ast_print_options_set_print_user> |
| is called whenever a node of type C<isl_ast_node_user> needs to |
| be printed. |
| The callback set by C<isl_ast_print_options_set_print_for> |
| is called whenever a node of type C<isl_ast_node_for> needs to |
| be printed. |
| Note that C<isl_ast_node_for_print> will I<not> call the |
| callback set by C<isl_ast_print_options_set_print_for> on the node |
| on which C<isl_ast_node_for_print> is called, but only on nested |
| nodes of type C<isl_ast_node_for>. It is therefore safe to |
| call C<isl_ast_node_for_print> from within the callback set by |
| C<isl_ast_print_options_set_print_for>. |
| |
| The following option determines the type to be used for iterators |
| while printing the AST. |
| |
| isl_stat isl_options_set_ast_iterator_type( |
| isl_ctx *ctx, const char *val); |
| const char *isl_options_get_ast_iterator_type( |
| isl_ctx *ctx); |
| |
| The AST printer only prints body nodes as blocks if these |
| blocks cannot be safely omitted. |
| For example, a C<for> node with one body node will not be |
| surrounded with braces in C<ISL_FORMAT_C>. |
| A block will always be printed by setting the following option. |
| |
| isl_stat isl_options_set_ast_always_print_block(isl_ctx *ctx, |
| int val); |
| int isl_options_get_ast_always_print_block(isl_ctx *ctx); |
| |
| =head3 Options |
| |
| #include <isl/ast_build.h> |
| isl_stat isl_options_set_ast_build_atomic_upper_bound( |
| isl_ctx *ctx, int val); |
| int isl_options_get_ast_build_atomic_upper_bound( |
| isl_ctx *ctx); |
| isl_stat isl_options_set_ast_build_prefer_pdiv(isl_ctx *ctx, |
| int val); |
| int isl_options_get_ast_build_prefer_pdiv(isl_ctx *ctx); |
| isl_stat isl_options_set_ast_build_detect_min_max( |
| isl_ctx *ctx, int val); |
| int isl_options_get_ast_build_detect_min_max( |
| isl_ctx *ctx); |
| isl_stat isl_options_set_ast_build_exploit_nested_bounds( |
| isl_ctx *ctx, int val); |
| int isl_options_get_ast_build_exploit_nested_bounds( |
| isl_ctx *ctx); |
| isl_stat isl_options_set_ast_build_group_coscheduled( |
| isl_ctx *ctx, int val); |
| int isl_options_get_ast_build_group_coscheduled( |
| isl_ctx *ctx); |
| isl_stat isl_options_set_ast_build_separation_bounds( |
| isl_ctx *ctx, int val); |
| int isl_options_get_ast_build_separation_bounds( |
| isl_ctx *ctx); |
| isl_stat isl_options_set_ast_build_scale_strides( |
| isl_ctx *ctx, int val); |
| int isl_options_get_ast_build_scale_strides( |
| isl_ctx *ctx); |
| isl_stat isl_options_set_ast_build_allow_else(isl_ctx *ctx, |
| int val); |
| int isl_options_get_ast_build_allow_else(isl_ctx *ctx); |
| isl_stat isl_options_set_ast_build_allow_or(isl_ctx *ctx, |
| int val); |
| int isl_options_get_ast_build_allow_or(isl_ctx *ctx); |
| |
| =over |
| |
| =item * ast_build_atomic_upper_bound |
| |
| Generate loop upper bounds that consist of the current loop iterator, |
| an operator and an expression not involving the iterator. |
| If this option is not set, then the current loop iterator may appear |
| several times in the upper bound. |
| For example, when this option is turned off, AST generation |
| for the schedule |
| |
| [n] -> { A[i] -> [i] : 0 <= i <= 100, n } |
| |
| produces |
| |
| for (int c0 = 0; c0 <= 100 && n >= c0; c0 += 1) |
| A(c0); |
| |
| When the option is turned on, the following AST is generated |
| |
| for (int c0 = 0; c0 <= min(100, n); c0 += 1) |
| A(c0); |
| |
| =item * ast_build_prefer_pdiv |
| |
| If this option is turned off, then the AST generation will |
| produce ASTs that may only contain C<isl_ast_op_fdiv_q> |
| operators, but no C<isl_ast_op_pdiv_q> or |
| C<isl_ast_op_pdiv_r> operators. |
| If this option is turned on, then C<isl> will try to convert |
| some of the C<isl_ast_op_fdiv_q> operators to (expressions containing) |
| C<isl_ast_op_pdiv_q> or C<isl_ast_op_pdiv_r> operators. |
| |
| =item * ast_build_detect_min_max |
| |
| If this option is turned on, then C<isl> will try and detect |
| min or max-expressions when building AST expressions from |
| piecewise affine expressions. |
| |
| =item * ast_build_exploit_nested_bounds |
| |
| Simplify conditions based on bounds of nested for loops. |
| In particular, remove conditions that are implied by the fact |
| that one or more nested loops have at least one iteration, |
| meaning that the upper bound is at least as large as the lower bound. |
| For example, when this option is turned off, AST generation |
| for the schedule |
| |
| [N,M] -> { A[i,j] -> [i,j] : 0 <= i <= N and |
| 0 <= j <= M } |
| |
| produces |
| |
| if (M >= 0) |
| for (int c0 = 0; c0 <= N; c0 += 1) |
| for (int c1 = 0; c1 <= M; c1 += 1) |
| A(c0, c1); |
| |
| When the option is turned on, the following AST is generated |
| |
| for (int c0 = 0; c0 <= N; c0 += 1) |
| for (int c1 = 0; c1 <= M; c1 += 1) |
| A(c0, c1); |
| |
| =item * ast_build_group_coscheduled |
| |
| If two domain elements are assigned the same schedule point, then |
| they may be executed in any order and they may even appear in different |
| loops. If this options is set, then the AST generator will make |
| sure that coscheduled domain elements do not appear in separate parts |
| of the AST. This is useful in case of nested AST generation |
| if the outer AST generation is given only part of a schedule |
| and the inner AST generation should handle the domains that are |
| coscheduled by this initial part of the schedule together. |
| For example if an AST is generated for a schedule |
| |
| { A[i] -> [0]; B[i] -> [0] } |
| |
| then the C<isl_ast_build_set_create_leaf> callback described |
| below may get called twice, once for each domain. |
| Setting this option ensures that the callback is only called once |
| on both domains together. |
| |
| =item * ast_build_separation_bounds |
| |
| This option specifies which bounds to use during separation. |
| If this option is set to C<ISL_AST_BUILD_SEPARATION_BOUNDS_IMPLICIT> |
| then all (possibly implicit) bounds on the current dimension will |
| be used during separation. |
| If this option is set to C<ISL_AST_BUILD_SEPARATION_BOUNDS_EXPLICIT> |
| then only those bounds that are explicitly available will |
| be used during separation. |
| |
| =item * ast_build_scale_strides |
| |
| This option specifies whether the AST generator is allowed |
| to scale down iterators of strided loops. |
| |
| =item * ast_build_allow_else |
| |
| This option specifies whether the AST generator is allowed |
| to construct if statements with else branches. |
| |
| =item * ast_build_allow_or |
| |
| This option specifies whether the AST generator is allowed |
| to construct if conditions with disjunctions. |
| |
| =back |
| |
| =head3 AST Generation Options (Schedule Tree) |
| |
| In case of AST construction from a schedule tree, the options |
| that control how an AST is created from the individual schedule |
| dimensions are stored in the band nodes of the tree |
| (see L</"Schedule Trees">). |
| |
| In particular, a schedule dimension can be handled in four |
| different ways, atomic, separate, unroll or the default. |
| This loop AST generation type can be set using |
| C<isl_schedule_node_band_member_set_ast_loop_type>. |
| Alternatively, |
| the first three can be selected by including a one-dimensional |
| element with as value the position of the schedule dimension |
| within the band and as name one of C<atomic>, C<separate> |
| or C<unroll> in the options |
| set by C<isl_schedule_node_band_set_ast_build_options>. |
| Only one of these three may be specified for |
| any given schedule dimension within a band node. |
| If none of these is specified, then the default |
| is used. The meaning of the options is as follows. |
| |
| =over |
| |
| =item C<atomic> |
| |
| When this option is specified, the AST generator will make |
| sure that a given domains space only appears in a single |
| loop at the specified level. |
| |
| For example, for the schedule tree |
| |
| domain: "{ a[i] : 0 <= i < 10; b[i] : 0 <= i < 10 }" |
| child: |
| schedule: "[{ a[i] -> [i]; b[i] -> [i+1] }]" |
| options: "{ atomic[x] }" |
| |
| the following AST will be generated |
| |
| for (int c0 = 0; c0 <= 10; c0 += 1) { |
| if (c0 >= 1) |
| b(c0 - 1); |
| if (c0 <= 9) |
| a(c0); |
| } |
| |
| On the other hand, for the schedule tree |
| |
| domain: "{ a[i] : 0 <= i < 10; b[i] : 0 <= i < 10 }" |
| child: |
| schedule: "[{ a[i] -> [i]; b[i] -> [i+1] }]" |
| options: "{ separate[x] }" |
| |
| the following AST will be generated |
| |
| { |
| a(0); |
| for (int c0 = 1; c0 <= 9; c0 += 1) { |
| b(c0 - 1); |
| a(c0); |
| } |
| b(9); |
| } |
| |
| If neither C<atomic> nor C<separate> is specified, then the AST generator |
| may produce either of these two results or some intermediate form. |
| |
| =item C<separate> |
| |
| When this option is specified, the AST generator will |
| split the domain of the specified schedule dimension |
| into pieces with a fixed set of statements for which |
| instances need to be executed by the iterations in |
| the schedule domain part. This option tends to avoid |
| the generation of guards inside the corresponding loops. |
| See also the C<atomic> option. |
| |
| =item C<unroll> |
| |
| When this option is specified, the AST generator will |
| I<completely> unroll the corresponding schedule dimension. |
| It is the responsibility of the user to ensure that such |
| unrolling is possible. |
| To obtain a partial unrolling, the user should apply an additional |
| strip-mining to the schedule and fully unroll the inner schedule |
| dimension. |
| |
| =back |
| |
| The C<isolate> option is a bit more involved. It allows the user |
| to isolate a range of schedule dimension values from smaller and |
| greater values. Additionally, the user may specify a different |
| atomic/separate/unroll choice for the isolated part and the remaining |
| parts. The typical use case of the C<isolate> option is to isolate |
| full tiles from partial tiles. |
| The part that needs to be isolated may depend on outer schedule dimensions. |
| The option therefore needs to be able to reference those outer schedule |
| dimensions. In particular, the space of the C<isolate> option is that |
| of a wrapped map with as domain the flat product of all outer band nodes |
| and as range the space of the current band node. |
| The atomic/separate/unroll choice for the isolated part is determined |
| by an option that lives in an unnamed wrapped space with as domain |
| a zero-dimensional C<isolate> space and as range the regular |
| C<atomic>, C<separate> or C<unroll> space. |
| This option may also be set directly using |
| C<isl_schedule_node_band_member_set_isolate_ast_loop_type>. |
| The atomic/separate/unroll choice for the remaining part is determined |
| by the regular C<atomic>, C<separate> or C<unroll> option. |
| Since the C<isolate> option references outer schedule dimensions, |
| its use in a band node causes any tree containing the node |
| to be considered anchored. |
| |
| As an example, consider the isolation of full tiles from partial tiles |
| in a tiling of a triangular domain. The original schedule is as follows. |
| |
| domain: "{ A[i,j] : 0 <= i,j and i + j <= 100 }" |
| child: |
| schedule: "[{ A[i,j] -> [floor(i/10)] }, \ |
| { A[i,j] -> [floor(j/10)] }, \ |
| { A[i,j] -> [i] }, { A[i,j] -> [j] }]" |
| |
| The output is |
| |
| for (int c0 = 0; c0 <= 10; c0 += 1) |
| for (int c1 = 0; c1 <= -c0 + 10; c1 += 1) |
| for (int c2 = 10 * c0; |
| c2 <= min(10 * c0 + 9, -10 * c1 + 100); c2 += 1) |
| for (int c3 = 10 * c1; |
| c3 <= min(10 * c1 + 9, -c2 + 100); c3 += 1) |
| A(c2, c3); |
| |
| Isolating the full tiles, we have the following input |
| |
| domain: "{ A[i,j] : 0 <= i,j and i + j <= 100 }" |
| child: |
| schedule: "[{ A[i,j] -> [floor(i/10)] }, \ |
| { A[i,j] -> [floor(j/10)] }, \ |
| { A[i,j] -> [i] }, { A[i,j] -> [j] }]" |
| options: "{ isolate[[] -> [a,b,c,d]] : 0 <= 10a,10b and \ |
| 10a+9+10b+9 <= 100 }" |
| |
| and output |
| |
| { |
| for (int c0 = 0; c0 <= 8; c0 += 1) { |
| for (int c1 = 0; c1 <= -c0 + 8; c1 += 1) |
| for (int c2 = 10 * c0; |
| c2 <= 10 * c0 + 9; c2 += 1) |
| for (int c3 = 10 * c1; |
| c3 <= 10 * c1 + 9; c3 += 1) |
| A(c2, c3); |
| for (int c1 = -c0 + 9; c1 <= -c0 + 10; c1 += 1) |
| for (int c2 = 10 * c0; |
| c2 <= min(10 * c0 + 9, -10 * c1 + 100); c2 += 1) |
| for (int c3 = 10 * c1; |
| c3 <= min(10 * c1 + 9, -c2 + 100); c3 += 1) |
| A(c2, c3); |
| } |
| for (int c0 = 9; c0 <= 10; c0 += 1) |
| for (int c1 = 0; c1 <= -c0 + 10; c1 += 1) |
| for (int c2 = 10 * c0; |
| c2 <= min(10 * c0 + 9, -10 * c1 + 100); c2 += 1) |
| for (int c3 = 10 * c1; |
| c3 <= min(10 * c1 + 9, -c2 + 100); c3 += 1) |
| A(c2, c3); |
| } |
| |
| We may then additionally unroll the innermost loop of the isolated part |
| |
| domain: "{ A[i,j] : 0 <= i,j and i + j <= 100 }" |
| child: |
| schedule: "[{ A[i,j] -> [floor(i/10)] }, \ |
| { A[i,j] -> [floor(j/10)] }, \ |
| { A[i,j] -> [i] }, { A[i,j] -> [j] }]" |
| options: "{ isolate[[] -> [a,b,c,d]] : 0 <= 10a,10b and \ |
| 10a+9+10b+9 <= 100; [isolate[] -> unroll[3]] }" |
| |
| to obtain |
| |
| { |
| for (int c0 = 0; c0 <= 8; c0 += 1) { |
| for (int c1 = 0; c1 <= -c0 + 8; c1 += 1) |
| for (int c2 = 10 * c0; c2 <= 10 * c0 + 9; c2 += 1) { |
| A(c2, 10 * c1); |
| A(c2, 10 * c1 + 1); |
| A(c2, 10 * c1 + 2); |
| A(c2, 10 * c1 + 3); |
| A(c2, 10 * c1 + 4); |
| A(c2, 10 * c1 + 5); |
| A(c2, 10 * c1 + 6); |
| A(c2, 10 * c1 + 7); |
| A(c2, 10 * c1 + 8); |
| A(c2, 10 * c1 + 9); |
| } |
| for (int c1 = -c0 + 9; c1 <= -c0 + 10; c1 += 1) |
| for (int c2 = 10 * c0; |
| c2 <= min(10 * c0 + 9, -10 * c1 + 100); c2 += 1) |
| for (int c3 = 10 * c1; |
| c3 <= min(10 * c1 + 9, -c2 + 100); c3 += 1) |
| A(c2, c3); |
| } |
| for (int c0 = 9; c0 <= 10; c0 += 1) |
| for (int c1 = 0; c1 <= -c0 + 10; c1 += 1) |
| for (int c2 = 10 * c0; |
| c2 <= min(10 * c0 + 9, -10 * c1 + 100); c2 += 1) |
| for (int c3 = 10 * c1; |
| c3 <= min(10 * c1 + 9, -c2 + 100); c3 += 1) |
| A(c2, c3); |
| } |
| |
| |
| =head3 AST Generation Options (Schedule Map) |
| |
| In case of AST construction using |
| C<isl_ast_build_node_from_schedule_map>, the options |
| that control how an AST is created from the individual schedule |
| dimensions are stored in the C<isl_ast_build>. |
| They can be set using the following function. |
| |
| #include <isl/ast_build.h> |
| __isl_give isl_ast_build * |
| isl_ast_build_set_options( |
| __isl_take isl_ast_build *build, |
| __isl_take isl_union_map *options); |
| |
| The options are encoded in an C<isl_union_map>. |
| The domain of this union relation refers to the schedule domain, |
| i.e., the range of the schedule passed |
| to C<isl_ast_build_node_from_schedule_map>. |
| In the case of nested AST generation (see L</"Nested AST Generation">), |
| the domain of C<options> should refer to the extra piece of the schedule. |
| That is, it should be equal to the range of the wrapped relation in the |
| range of the schedule. |
| The range of the options can consist of elements in one or more spaces, |
| the names of which determine the effect of the option. |
| The values of the range typically also refer to the schedule dimension |
| to which the option applies, with value C<0> representing |
| the outermost schedule dimension. In case of nested AST generation |
| (see L</"Nested AST Generation">), these values refer to the position |
| of the schedule dimension within the innermost AST generation. |
| The constraints on the domain elements of |
| the option should only refer to this dimension and earlier dimensions. |
| We consider the following spaces. |
| |
| =over |
| |
| =item C<separation_class> |
| |
| B<This option has been deprecated. Use the isolate option on |
| schedule trees instead.> |
| |
| This space is a wrapped relation between two one dimensional spaces. |
| The input space represents the schedule dimension to which the option |
| applies and the output space represents the separation class. |
| While constructing a loop corresponding to the specified schedule |
| dimension(s), the AST generator will try to generate separate loops |
| for domain elements that are assigned different classes. |
| If only some of the elements are assigned a class, then those elements |
| that are not assigned any class will be treated as belonging to a class |
| that is separate from the explicitly assigned classes. |
| The typical use case for this option is to separate full tiles from |
| partial tiles. |
| The other options, described below, are applied after the separation |
| into classes. |
| |
| As an example, consider the separation into full and partial tiles |
| of a tiling of a triangular domain. |
| Take, for example, the domain |
| |
| { A[i,j] : 0 <= i,j and i + j <= 100 } |
| |
| and a tiling into tiles of 10 by 10. The input to the AST generator |
| is then the schedule |
| |
| { A[i,j] -> [([i/10]),[j/10],i,j] : 0 <= i,j and |
| i + j <= 100 } |
| |
| Without any options, the following AST is generated |
| |
| for (int c0 = 0; c0 <= 10; c0 += 1) |
| for (int c1 = 0; c1 <= -c0 + 10; c1 += 1) |
| for (int c2 = 10 * c0; |
| c2 <= min(-10 * c1 + 100, 10 * c0 + 9); |
| c2 += 1) |
| for (int c3 = 10 * c1; |
| c3 <= min(10 * c1 + 9, -c2 + 100); |
| c3 += 1) |
| A(c2, c3); |
| |
| Separation into full and partial tiles can be obtained by assigning |
| a class, say C<0>, to the full tiles. The full tiles are represented by those |
| values of the first and second schedule dimensions for which there are |
| values of the third and fourth dimensions to cover an entire tile. |
| That is, we need to specify the following option |
| |
| { [a,b,c,d] -> separation_class[[0]->[0]] : |
| exists b': 0 <= 10a,10b' and |
| 10a+9+10b'+9 <= 100; |
| [a,b,c,d] -> separation_class[[1]->[0]] : |
| 0 <= 10a,10b and 10a+9+10b+9 <= 100 } |
| |
| which simplifies to |
| |
| { [a, b, c, d] -> separation_class[[1] -> [0]] : |
| a >= 0 and b >= 0 and b <= 8 - a; |
| [a, b, c, d] -> separation_class[[0] -> [0]] : |
| a >= 0 and a <= 8 } |
| |
| With this option, the generated AST is as follows |
| |
| { |
| for (int c0 = 0; c0 <= 8; c0 += 1) { |
| for (int c1 = 0; c1 <= -c0 + 8; c1 += 1) |
| for (int c2 = 10 * c0; |
| c2 <= 10 * c0 + 9; c2 += 1) |
| for (int c3 = 10 * c1; |
| c3 <= 10 * c1 + 9; c3 += 1) |
| A(c2, c3); |
| for (int c1 = -c0 + 9; c1 <= -c0 + 10; c1 += 1) |
| for (int c2 = 10 * c0; |
| c2 <= min(-10 * c1 + 100, 10 * c0 + 9); |
| c2 += 1) |
| for (int c3 = 10 * c1; |
| c3 <= min(-c2 + 100, 10 * c1 + 9); |
| c3 += 1) |
| A(c2, c3); |
| } |
| for (int c0 = 9; c0 <= 10; c0 += 1) |
| for (int c1 = 0; c1 <= -c0 + 10; c1 += 1) |
| for (int c2 = 10 * c0; |
| c2 <= min(-10 * c1 + 100, 10 * c0 + 9); |
| c2 += 1) |
| for (int c3 = 10 * c1; |
| c3 <= min(10 * c1 + 9, -c2 + 100); |
| c3 += 1) |
| A(c2, c3); |
| } |
| |
| =item C<separate> |
| |
| This is a single-dimensional space representing the schedule dimension(s) |
| to which ``separation'' should be applied. Separation tries to split |
| a loop into several pieces if this can avoid the generation of guards |
| inside the loop. |
| See also the C<atomic> option. |
| |
| =item C<atomic> |
| |
| This is a single-dimensional space representing the schedule dimension(s) |
| for which the domains should be considered ``atomic''. That is, the |
| AST generator will make sure that any given domain space will only appear |
| in a single loop at the specified level. |
| |
| Consider the following schedule |
| |
| { a[i] -> [i] : 0 <= i < 10; |
| b[i] -> [i+1] : 0 <= i < 10 } |
| |
| If the following option is specified |
| |
| { [i] -> separate[x] } |
| |
| then the following AST will be generated |
| |
| { |
| a(0); |
| for (int c0 = 1; c0 <= 9; c0 += 1) { |
| a(c0); |
| b(c0 - 1); |
| } |
| b(9); |
| } |
| |
| If, on the other hand, the following option is specified |
| |
| { [i] -> atomic[x] } |
| |
| then the following AST will be generated |
| |
| for (int c0 = 0; c0 <= 10; c0 += 1) { |
| if (c0 <= 9) |
| a(c0); |
| if (c0 >= 1) |
| b(c0 - 1); |
| } |
| |
| If neither C<atomic> nor C<separate> is specified, then the AST generator |
| may produce either of these two results or some intermediate form. |
| |
| =item C<unroll> |
| |
| This is a single-dimensional space representing the schedule dimension(s) |
| that should be I<completely> unrolled. |
| To obtain a partial unrolling, the user should apply an additional |
| strip-mining to the schedule and fully unroll the inner loop. |
| |
| =back |
| |
| =head3 Fine-grained Control over AST Generation |
| |
| Besides specifying the constraints on the parameters, |
| an C<isl_ast_build> object can be used to control |
| various aspects of the AST generation process. |
| In case of AST construction using |
| C<isl_ast_build_node_from_schedule_map>, |
| the most prominent way of control is through ``options'', |
| as explained above. |
| |
| Additional control is available through the following functions. |
| |
| #include <isl/ast_build.h> |
| __isl_give isl_ast_build * |
| isl_ast_build_set_iterators( |
| __isl_take isl_ast_build *build, |
| __isl_take isl_id_list *iterators); |
| |
| The function C<isl_ast_build_set_iterators> allows the user to |
| specify a list of iterator C<isl_id>s to be used as iterators. |
| If the input schedule is injective, then |
| the number of elements in this list should be as large as the dimension |
| of the schedule space, but no direct correspondence should be assumed |
| between dimensions and elements. |
| If the input schedule is not injective, then an additional number |
| of C<isl_id>s equal to the largest dimension of the input domains |
| may be required. |
| If the number of provided C<isl_id>s is insufficient, then additional |
| names are automatically generated. |
| |
| #include <isl/ast_build.h> |
| __isl_give isl_ast_build * |
| isl_ast_build_set_create_leaf( |
| __isl_take isl_ast_build *build, |
| __isl_give isl_ast_node *(*fn)( |
| __isl_take isl_ast_build *build, |
| void *user), void *user); |
| |
| The |
| C<isl_ast_build_set_create_leaf> function allows for the |
| specification of a callback that should be called whenever the AST |
| generator arrives at an element of the schedule domain. |
| The callback should return an AST node that should be inserted |
| at the corresponding position of the AST. The default action (when |
| the callback is not set) is to continue generating parts of the AST to scan |
| all the domain elements associated to the schedule domain element |
| and to insert user nodes, ``calling'' the domain element, for each of them. |
| The C<build> argument contains the current state of the C<isl_ast_build>. |
| To ease nested AST generation (see L</"Nested AST Generation">), |
| all control information that is |
| specific to the current AST generation such as the options and |
| the callbacks has been removed from this C<isl_ast_build>. |
| The callback would typically return the result of a nested |
| AST generation or a |
| user defined node created using the following function. |
| |
| #include <isl/ast.h> |
| __isl_give isl_ast_node *isl_ast_node_alloc_user( |
| __isl_take isl_ast_expr *expr); |
| |
| #include <isl/ast_build.h> |
| __isl_give isl_ast_build * |
| isl_ast_build_set_at_each_domain( |
| __isl_take isl_ast_build *build, |
| __isl_give isl_ast_node *(*fn)( |
| __isl_take isl_ast_node *node, |
| __isl_keep isl_ast_build *build, |
| void *user), void *user); |
| __isl_give isl_ast_build * |
| isl_ast_build_set_before_each_for( |
| __isl_take isl_ast_build *build, |
| __isl_give isl_id *(*fn)( |
| __isl_keep isl_ast_build *build, |
| void *user), void *user); |
| __isl_give isl_ast_build * |
| isl_ast_build_set_after_each_for( |
| __isl_take isl_ast_build *build, |
| __isl_give isl_ast_node *(*fn)( |
| __isl_take isl_ast_node *node, |
| __isl_keep isl_ast_build *build, |
| void *user), void *user); |
| __isl_give isl_ast_build * |
| isl_ast_build_set_before_each_mark( |
| __isl_take isl_ast_build *build, |
| isl_stat (*fn)(__isl_keep isl_id *mark, |
| __isl_keep isl_ast_build *build, |
| void *user), void *user); |
| __isl_give isl_ast_build * |
| isl_ast_build_set_after_each_mark( |
| __isl_take isl_ast_build *build, |
| __isl_give isl_ast_node *(*fn)( |
| __isl_take isl_ast_node *node, |
| __isl_keep isl_ast_build *build, |
| void *user), void *user); |
| |
| The callback set by C<isl_ast_build_set_at_each_domain> will |
| be called for each domain AST node. |
| The callbacks set by C<isl_ast_build_set_before_each_for> |
| and C<isl_ast_build_set_after_each_for> will be called |
| for each for AST node. The first will be called in depth-first |
| pre-order, while the second will be called in depth-first post-order. |
| Since C<isl_ast_build_set_before_each_for> is called before the for |
| node is actually constructed, it is only passed an C<isl_ast_build>. |
| The returned C<isl_id> will be added as an annotation (using |
| C<isl_ast_node_set_annotation>) to the constructed for node. |
| In particular, if the user has also specified an C<after_each_for> |
| callback, then the annotation can be retrieved from the node passed to |
| that callback using C<isl_ast_node_get_annotation>. |
| The callbacks set by C<isl_ast_build_set_before_each_mark> |
| and C<isl_ast_build_set_after_each_mark> will be called for each |
| mark AST node that is created, i.e., for each mark schedule node |
| in the input schedule tree. The first will be called in depth-first |
| pre-order, while the second will be called in depth-first post-order. |
| Since the callback set by C<isl_ast_build_set_before_each_mark> |
| is called before the mark AST node is actually constructed, it is passed |
| the identifier of the mark node. |
| All callbacks should C<NULL> (or C<isl_stat_error>) on failure. |
| The given C<isl_ast_build> can be used to create new |
| C<isl_ast_expr> objects using C<isl_ast_build_expr_from_pw_aff> |
| or C<isl_ast_build_call_from_pw_multi_aff>. |
| |
| =head3 Nested AST Generation |
| |
| C<isl> allows the user to create an AST within the context |
| of another AST. These nested ASTs are created using the |
| same C<isl_ast_build_node_from_schedule_map> function that is used to create |
| the outer AST. The C<build> argument should be an C<isl_ast_build> |
| passed to a callback set by |
| C<isl_ast_build_set_create_leaf>. |
| The space of the range of the C<schedule> argument should refer |
| to this build. In particular, the space should be a wrapped |
| relation and the domain of this wrapped relation should be the |
| same as that of the range of the schedule returned by |
| C<isl_ast_build_get_schedule> below. |
| In practice, the new schedule is typically |
| created by calling C<isl_union_map_range_product> on the old schedule |
| and some extra piece of the schedule. |
| The space of the schedule domain is also available from |
| the C<isl_ast_build>. |
| |
| #include <isl/ast_build.h> |
| __isl_give isl_union_map *isl_ast_build_get_schedule( |
| __isl_keep isl_ast_build *build); |
| __isl_give isl_space *isl_ast_build_get_schedule_space( |
| __isl_keep isl_ast_build *build); |
| __isl_give isl_ast_build *isl_ast_build_restrict( |
| __isl_take isl_ast_build *build, |
| __isl_take isl_set *set); |
| |
| The C<isl_ast_build_get_schedule> function returns a (partial) |
| schedule for the domains elements for which part of the AST still needs to |
| be generated in the current build. |
| In particular, the domain elements are mapped to those iterations of the loops |
| enclosing the current point of the AST generation inside which |
| the domain elements are executed. |
| No direct correspondence between |
| the input schedule and this schedule should be assumed. |
| The space obtained from C<isl_ast_build_get_schedule_space> can be used |
| to create a set for C<isl_ast_build_restrict> to intersect |
| with the current build. In particular, the set passed to |
| C<isl_ast_build_restrict> can have additional parameters. |
| The ids of the set dimensions in the space returned by |
| C<isl_ast_build_get_schedule_space> correspond to the |
| iterators of the already generated loops. |
| The user should not rely on the ids of the output dimensions |
| of the relations in the union relation returned by |
| C<isl_ast_build_get_schedule> having any particular value. |
| |
| =head1 Applications |
| |
| Although C<isl> is mainly meant to be used as a library, |
| it also contains some basic applications that use some |
| of the functionality of C<isl>. |
| For applications that take one or more polytopes or polyhedra |
| as input, this input may be specified in either the L<isl format> |
| or the L<PolyLib format>. |
| |
| =head2 C<isl_polyhedron_sample> |
| |
| C<isl_polyhedron_sample> takes a polyhedron as input and prints |
| an integer element of the polyhedron, if there is any. |
| The first column in the output is the denominator and is always |
| equal to 1. If the polyhedron contains no integer points, |
| then a vector of length zero is printed. |
| |
| =head2 C<isl_pip> |
| |
| C<isl_pip> takes the same input as the C<example> program |
| from the C<piplib> distribution, i.e., a set of constraints |
| on the parameters, a line containing only -1 and finally a set |
| of constraints on a parametric polyhedron. |
| The coefficients of the parameters appear in the last columns |
| (but before the final constant column). |
| The output is the lexicographic minimum of the parametric polyhedron. |
| As C<isl> currently does not have its own output format, the output |
| is just a dump of the internal state. |
| |
| =head2 C<isl_polyhedron_minimize> |
| |
| C<isl_polyhedron_minimize> computes the minimum of some linear |
| or affine objective function over the integer points in a polyhedron. |
| If an affine objective function |
| is given, then the constant should appear in the last column. |
| |
| =head2 C<isl_polytope_scan> |
| |
| Given a polytope, C<isl_polytope_scan> prints |
| all integer points in the polytope. |
| |
| =head2 C<isl_flow> |
| |
| Given an C<isl_union_access_info> object as input, |
| C<isl_flow> prints out the corresponding dependences, |
| as computed by C<isl_union_access_info_compute_flow>. |
| |
| =head2 C<isl_codegen> |
| |
| Given either a schedule tree or a sequence consisting of |
| a schedule map, a context set and an options relation, |
| C<isl_codegen> prints out an AST that scans the domain elements |
| of the schedule in the order of their image(s) taking into account |
| the constraints in the context set. |
| |
| =head2 C<isl_schedule> |
| |
| Given an C<isl_schedule_constraints> object as input, |
| C<isl_schedule> prints out a schedule that satisfies the given |
| constraints. |