整数线性规划求解工具isl使用方法
整数线性规划求解工具 Integer Set Library
代码
参考
isl是一个用于多面体模型调度实现的c/c++库。通过isl,我们可以对模型进行自动的调度,循环优化等。
编译
ISL,Integer Set Library
版本0.22.1,http://isl.gforge.inria.fr/
README关于编译的部分说了
./configure
make
make install
使用./configure --help阅读后针对本地环境,使用
./configure --prefix=/opt/isl --enable-shared=yes --enable-static=yes \
CC=/opt/gcc/bin/gcc \
CFLAGS="-O3 -I/opt/gmp/include" \
LDFLAGS="-L/opt/gmp/lib -Wl,--rpath=/opt/gmp/lib" \
CXX=/opt/gcc-10.2.0/bin/g++ \
CXXFLAGS="-I/opt/gmp/include" \
PYTHON=/opt/python3/bin/python3 \
--enable-fast-install=no --with-gnu-ld
make
make install
islpy python接口
isl内部对象介绍
- 1.isl_ctx对象的创建(初始化):
整数集和关系的所有操作都在的上下文中发生isl_ctx。给定isl_ctx只能在单个线程中使用。一个函数的所有参数都必须在同一上下文中分配。当前没有功能可用于将对象从一个移动isl_ctx到另一个isl_ctx。这意味着当前无法安全地将对象从一个线程移动到另一个线程,除非整个线程isl_ctx都移动了。
一个isl_ctx可以使用分配isl_ctx_alloc和使用中解脱出来isl_ctx_free。在isl_ctx释放之前,应释放内分配的所有对象isl_ctx。
isl_ctx 对象就像一根线一样把上下文关系(对象)连接起来。
isl_ctx *isl_ctx_alloc();
void isl_ctx_free(isl_ctx *ctx);
测试:
isl_ctx *isl = isl_ctx_alloc(); // 创建对象
cout << isl << endl;
isl_ctx_free(isl); // 释放
输出是一个地址值,可以看出来该指针指向一个对象。
同时,我们还可以为 isl_ctx 对象指定低级 op 数量的范围(bound)。例如:
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);
上面说了ctx相当于线将各种对象连接起来,那么我们还可以通过上下文对象来得到ctx:
#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);
isl_ctx *isl_multi_id_get_ctx(__isl_keep isl_multi_id *mi);#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);
- 2.返回的结果
isl isl_size对返回非负值(通常是数字或位置)的函数使用特殊的返回类型。除了常规的非负返回值外,isl_size_error还可能返回一个特殊的(负)值,表明出错。
isl对于返回布尔值或原则上不返回任何值的函数,它也使用两种特殊的返回类型。特别是,该isl_bool类型具有三个可能的值:(isl_bool_true一个正整数),表示true或yes;isl_bool_false(整数值零),表示false或no;和isl_bool_error(负整数值),表示出了点问题。在上定义了以下操作isl_bool。该函数isl_bool_not可以被用于否定的isl_bool,其中的否定isl_bool_error是isl_bool_error一次。该函数isl_bool_ok将整数转换为isl_bool。任何非零值的收益率isl_bool_true和零收益率isl_bool_false。
bool
int a = 0;
isl_bool result = isl_bool_ok(a);
cout << result << endl;
输出结果为0
- 3.isl_val对象
一个 isl_val 对象表示整数值,有理值或三个特殊值之一,即无穷大,负无穷大和正无穷大。可以使用以下功能创建一些预定义的值:
#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);
测试:
isl_val * val = isl_val_zero(isl);
cout << val << endl;
输出:
0x93c6080
可以使用以下函数创建特定的整数值:
#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);
一个isl_val可以使用下面的函数来修改:
#include <isl/val.h>
__isl_give isl_val *isl_val_set_si(__isl_take isl_val *v,long i);
可以使用以下功能复制和释放 isl_val 。
#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);
对于这样的数值对象我们还可以对其进行一元运算、二元运算等,具体运算函数可以参考文档。
- 3.集合(set)与关系或映射(map)
isl使用六种类型的代表集合和关系的对象,
isl_basic_set,
isl_basic_map,
isl_set,
isl_map,
isl_union_set 和
isl_union_map(这些其实都是对象)。
isl_basic_set和isl_basic_map分别代表可仿射约束的集合和关系,而isl_set和isl_map分别代表isl_basic_sets和isl_basic_maps 的并集。但是,所有isl_basic_sets或isl_basic_maps都必须居住在同一空间中。isl_union_sets和isl_union_maps表示isl_sets或isl_maps在不同空间中的并集,如果空间的维数和/或名称不同,则它们被认为是不同的(请参见“空间”)。集和关系(映射)之间的区别在于,set具有一组变量,而map具有两组变量,即输入变量和输出变量。
- 4.错误处理
isl在触发运行时错误时,支持不同的反应方式。例如,如果isl_map_intersect用两个具有不兼容空间的映射调用诸如之类的函数,则会出现运行时错误。有三种对错误做出反应的方式:警告,继续或中止。
默认行为是警告。在这种模式下,isl打印警告,将最后一个错误存储在相应isl_ctx的错误中,触发错误的函数将返回一个值,指示发生了某些错误。如果函数返回指针,则该值为NULL。在返回一个功能的情况下isl_size,isl_bool或者isl_stat,这个值isl_size_error,isl_bool_error或isl_stat_error。错误不会破坏内部状态,因此可以继续使用isl。isl还提供了读取上一个错误的功能,包括特定的错误消息,发生错误的isl源文件和行号,以及重置有关上一个错误的所有信息。最后的错误仅用于提供信息。它的存在不会改变的行为isl。因此,重新设置错误并不需要继续使用isl,而只是为了观察新的错误。
- 5.isl_id对象
标识符用于识别单个维度和维度元组。它们由一个可选的名称和一个可选的用户指针(代表该id对象标识哪个对象)组成。但是,名称和用户指针不能都为NULL。具有相同名称但指针值不同的标识符被认为是不同的。同样,具有不同名称但指针值相同的标识符也被认为是不同的。相同的标识符使用相同的对象表示。因此,可以使用==运算符测试成对的标识符是否相等。可以使用以下功能构造,复制,释放,检查和打印标识符。
#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);
使用示例:
isl_set *sum = isl_set_sum(set, set2); // 表示对set、set2这两个集合对象进行加法
isl_id *ids = isl_id_alloc(ctx, "sum", sum);// 定义一个id指向sum
char *str_id = isl_id_to_str(ids);
printf("id:%s\n", str_id);
最后输出如下,代表一个地址值:
id:sum@0x993a9e0
- 6.isl_space对象
每当从头开始创建新的set,map或类似对象时,都需要使用来指定其所处的空间isl_space。
每个空间包含零个或多个参数,以及零个,一个或两个元组的 set 或输入/输出维。参数和尺寸由isl_dim_type和标识。类型isl_dim_param是指参数,类型isl_dim_set是指设置维(对于具有单个元组的空间)和类型isl_dim_in,而类型isl_dim_out是指输入和输出维(对于具有两个元组的空间)。局部空间也包含类型的尺寸isl_dim_div。注意,参数仅由其在给定对象中的位置来标识。在不同的对象之间,参数(通常)由其名称或标识符标识。只有未命名的参数才能通过它们在对象之间的位置来标识。不建议使用未命名的参数。
对space的基本操作如下:
#include <isl/space.h>
__isl_give isl_space *isl_space_unit(isl_ctx *ctx);
__isl_give isl_space *isl_space_alloc(isl_ctx *ctx,unsigned nparam, unsigned n_in, unsigned n_out);//带进带出的专用于map
__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);
需要使用isl_space_unit或创建用于创建参数域的空间isl_space_params_alloc。对于其他集合,需要使用来创建空间isl_space_set_alloc,而对于关系而言,需要使用来创建空间isl_space_alloc。使用的isl_space_params_alloc,isl_space_set_alloc并且isl_space_alloc因为它们允许引进未命名参数是不鼓励。
要检查给定空间是集合空间还是映射空间,还是参数空间,请使用以下函数:
#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);
创建与其他对象位于同一空间的对象通常很有用。这可以通过基于原始对象的空间来创建新对象(请参见“创建新的集合和关系”或“函数”)来完成。
创建和一个多面体对象相同space的space:
#include <isl/polynomial.h>
isl_space *isl_qpolynomial_get_domain_space(isl_qpolynomial *qp);
isl_space *isl_qpolynomial_get_space(isl_qpolynomial *qp);
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/space.h>
__isl_give isl_space *isl_space_add_param_id(__isl_take isl_space *space,__isl_take isl_id *id);
相反,可以使用以下函数从空格中删除所有参数。
#include <isl/space.h>
__isl_give isl_space *isl_space_drop_all_params(__isl_take isl_space *space);
isl基本操作
-
1.create set & map
- Empty sets and relations
可以看出来。set和map的创建时凭借于space的。
__isl_give isl_basic_set *isl_basic_set_empty(__isl_take isl_space *space);//创建一个空的set空间
__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);
** 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);
** 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);
** 可以使用以下功能将基本集合或关系转换为集合或关系:
__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);
** 例如,要创建一个包含10到42之间的偶数整数的集合,可以使用以下代码。
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);
或者:
isl_basic_set *bset;
bset = isl_basic_set_read_from_str(ctx,"{[i] : exists (a : i = 2a and i >= 10 and i <= 42)}");
整体程序如下:
int main()
{isl_ctx *ctx = isl_ctx_alloc();isl_basic_set *bset;bset = isl_basic_set_read_from_str(ctx, "{[i] : exists (a : i = 2a and i >= 10 and i <= 42)}");const char *out = isl_basic_set_to_str(bset);cout << out << endl;return 0;
}
最终输出:
{ [i] : (i) mod 2 = 0 and 10 <= i <= 42 }
这便是一个最简单的调度编写,这种语法表示 i 是一个循环变量,接下来我们看一下,如何能从字符串创建相应的 set、map 等对象。
2.Input & output
对于集合和关系,isl支持其自己的输入/输出格式,该格式类似于该Omega格式,但PolyLib在某些情况下还支持该格式。对于其他对象类型,通常仅isl支持一种格式。
输入
例如从输入格式创建一个basic_set对象:
#include <stdio.h>
#include <isl/ctx.h>
#include <isl/set.h>
using namespace std;int main()
{isl_ctx *ctx = isl_ctx_alloc();//create a ctx objectisl_basic_set *bset;bset = isl_basic_set_read_from_str(ctx, "[n] -> { [i] : exists (a = [i/10] : 0 <= i and i <= n and i - 10 a <= 6) }");//表示 i % 10 <= 6char *out = isl_basic_set_to_str(bset);printf("%s\n", out);isl_basic_set_free(bset);isl_ctx_free(ctx);return 0;
}
输出结果:
n -> { [i] : 0 <= i <= n and 10*floor((3 + i)/10) <= i }
floor表示向下取整,可以看到isl帮我们把这样的循环变量进行了一些微调。
我们还可以使用以下的函数来从特定的输入格式创建相应对象:
#include <isl/id.h>
__isl_give isl_id *isl_id_read_from_str(isl_ctx *ctx,const char *str);//创建id对象
__isl_give isl_multi_id *isl_multi_id_read_from_str(isl_ctx *ctx, const char *str);#include <isl/val.h>
__isl_give isl_val *isl_val_read_from_str(isl_ctx *ctx,const char *str);//创建一个val对象
__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);
输出
在可以打印任何内容之前,需要先创建一个isl_printer对象:
__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);
isl_printer_to_file打印到给定的文件,同时isl_printer_to_str打印到可以使用以下函数提取的字符串。
#include <isl/printer.h>
__isl_give char *isl_printer_get_str(__isl_keep isl_printer *printer);
还是刚才的程序,我们继续用isl_printer对象来输出:
int main()
{isl_ctx *ctx = isl_ctx_alloc();//create a ctx objectisl_basic_set *bset;bset = isl_basic_set_read_from_str(ctx, "[n] -> { [i] : exists (a = [i/10] : 0 <= i and i <= n and i - 10 a <= 6) }");char *out = isl_basic_set_to_str(bset);printf("%s\n", out);isl_printer *p = isl_printer_to_str(ctx);p = isl_printer_print_basic_set(p, bset); //表示输出basic_setchar *out2 = isl_printer_get_str(p);printf("%s", out2);isl_printer_free(p);isl_basic_set_free(bset);isl_ctx_free(ctx);return 0;
}
输出结果为两行一样的循环变量约束:
n -> { [i] : 0 <= i <= n and 10floor((3 + i)/10) <= i }
n -> { [i] : 0 <= i <= n and 10floor((3 + i)/10) <= i }
另外,可以使用以下函数直接获取字符串表示形式,该函数始终以isl格式打印:
#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);
相关文章:
整数线性规划求解工具isl使用方法
整数线性规划求解工具 Integer Set Library 代码 参考 isl是一个用于多面体模型调度实现的c/c库。通过isl,我们可以对模型进行自动的调度,循环优化等。 编译 ISL,Integer Set Library 版本0.22.1,http://isl.gforge.inria.fr/ README关于…...

SystemC的调度器
文章目录 前言调度器初始化evaluatewait updatenotify delta notificationtime notification仿真结束 前言 SystemC是基于C的库,主要用来对 IC 进行功能建模和性能建模。有时也被用来当做 RTL (register transfer level) 级的升级版 HLS(High Level synthesis) 直接…...

SpringBoot、SpringCloud 版本查看
1、SpringBoot 官网地址 https://spring.io/projects/spring-boot#learn spring-boot-starter-parent 版本列表可查看: https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-parent 2、SpringCloud 官网地址 https://spring.io/pro…...

AI Chat 设计模式:12. 享元模式
本文是该系列的第十二篇,采用问答式的方式展开,问题由我提出,答案由 Chat AI 作出,灰色背景的文字则主要是我的一些思考和补充。 问题列表 Q.1 给我介绍一下享元模式A.1Q.2 也就是说,其实共享的是对象的内部状态&…...
Spring mvc:SpringServletContainerInitializer
SpringServletContainerInitializer实现了Servlet3.0规范中定义的ServletContainerInitializer: public interface ServletContainerInitializer {void onStartup(Set<Class<?>> c, ServletContext ctx) throws ServletException; }SpringServletCont…...

微信小程序中的全局数据共享(状态管理)使用介绍
开发工具:微信开发者工具Stable 1.06 一、状态管理简介 微信小程序全局状态是指可以在不同页面之间共享的数据或状态。 它可以存储用户的登录状态、个人信息、全局配置信息等。 二、安装MobX 1、安装NPM 在资源管理器的空白地方点右键,选择“在外部…...

LLM - LLama 模型读取报错 TypeError: not a string
一.引言 读取 LLama2 模型时报错 TypeError: not a string 看异常栈是 AutoTokenizer.from_pretrained 时候的异常。 二.问题解决 出现类似加载模型异常的问题,大致分两类: ◆ 模型地址异常 脚本里传的 pretrained_model Path 有问题,加 …...

2023年08月在线IDE流行度最新排名
点击查看最新在线IDE流行度最新排名(每月更新) 2023年08月在线IDE流行度最新排名 TOP 在线IDE排名是通过分析在线ide名称在谷歌上被搜索的频率而创建的 在线IDE被搜索的次数越多,人们就会认为它越受欢迎。原始数据来自谷歌Trends 如果您相…...
k8s的架构
简介 一个 K8s 系统,通常称为一个 K8s 集群,集群主要包括两个部分 一个 Master 节点(主节点) 一群 Node 节点(计算节点) Master节点 Master 节点包括 API Server、Scheduler、Controller manager、etcd A…...

数据分析基础-Excel图表的美化操作(按照教程一步步操作)
一、原始数据 包含月份和对应的销量和产量。 时间销量产量1月60722月38673月28344月58685月67596月72357月61428月24319月556710月243511月122112月2645 二、原始的图表设计-采用Excel自带模板 三、优化思路 1、删除多余元素 2、弱化次要元素 对于可以弱化的元素,…...
Mybatis嵌套查询(一对多)
一、返回数据Java类 Data public class PersonnelDetailsVO{/*** 主键*/Column(name "ID", length 36, precision 0)private String id;/*** 人员姓名*/Column(name "OPERATE_NAME", length 36, precision 0)private String operateName;/*** 单位i…...

web前端转正工作总结范文5篇
web前端转正工作总结(篇1) 来到__有限公司已经三个月了,目前的工作是前端开发,我是一名应届毕业生,之前没有过工作经验,在刚来到__这个大家庭的时候,我就被这里的工作气氛深深地吸引࿰…...
P1144 最短路计数
最短路计数 题目描述 给出一个 N N N 个顶点 M M M 条边的无向无权图,顶点编号为 1 ∼ N 1\sim N 1∼N。问从顶点 1 1 1 开始,到其他每个点的最短路有几条。 输入格式 第一行包含 2 2 2 个正整数 N , M N,M N,M,为图的顶点数与边数…...
Docker入门之命令
Docker命令学习方式 docker -h docker run --help # 这种形式参考 # 官方帮助 # https://docs.docker.com/reference/ Docker中命令是一等公民, 容器是为命令服务的,甚至启动容器都是为了执行一个命令 run docker run -i -t --name c1 centos:latest bash # 翻译: docker ru…...

Multimodal Learning with Transformer: A Survey
Transformer多模态学习 Abstract1 INTRODUCTION2 BACKGROUND2.1 Multimodal Learning (MML)2.2 Transformers: a Brief History and Milestones2.3 Multimodal Big Data 3 TRANSFORMERS: A GEOMETRICALLY TOPOLOGICAL PERSPECTIVE3.1 Vanilla Transformer3.1.1 Input Tokenizat…...

网工内推 | 实施、售后工程师,厂商认证优先
01 安井食品集团股份有限公司 招聘岗位:网络工程师 职责描述: 1.负责集团组网的网络规划、实施、维护工作; 2.负责公司局域网的网络规划、实施、维护工作; 3.负责公司企业安全系统规划、实施、维护工作; 4、负责公…...

小程序商品如何设置限购
限购是一种常用的小程序商品销售策略,可以帮助商家提高销售额、控制库存和增加用户的购买欲望。那么,小程序产品怎么设置限购呢?下面将为您详细介绍。 1. 设置限购数量 可以设置最低购买数量来鼓励用户批量购买或满足特定的销售需求。例如&…...
通信原理复习公式整理(自用/持续更新)
目录 符号表欧拉公式第一章平均信息量传信率(信息速率)传码率(码元速率) 第二章第三章第四章第五章第六章 数字信号的载波传输2ASK带宽余弦滚降基带信号-2ASK带宽2FSK带宽余弦滚降基带信号-2ASK带宽2PSK带宽匹配滤波器最大输出信噪比最佳线性滤波器传输特性ASK系统信号能量FSK系…...
TypeScript实战篇 - TS实战: 服务层开发 - 完整的聊天服务
目录 huatian-svc/src/main.ts huatian-svc/src/context/ChatContext.ts huatian-svc/src/ChatSession.ts huatian-svc/src/service/ChatIDService.ts huatian-svc/src/dao/DB.ts huatian-svc/src/dao/Dao.ts huatian-svc/src/dao/create_db.ts huatian-svc/src/main.ts…...

【雕爷学编程】MicroPython动手做(32)——物联网之MQTT
MQTT (Message Queuing Telemetry Transport)消息队列遥测传输协议,是一种基于发布/订阅(publish/subscribe)模式的"轻量级"通讯协议,该协议构建于TCP/IP协议上,由IBM在1999年发布。M…...

多云管理“拦路虎”:深入解析网络互联、身份同步与成本可视化的技术复杂度
一、引言:多云环境的技术复杂性本质 企业采用多云策略已从技术选型升维至生存刚需。当业务系统分散部署在多个云平台时,基础设施的技术债呈现指数级积累。网络连接、身份认证、成本管理这三大核心挑战相互嵌套:跨云网络构建数据…...
vscode里如何用git
打开vs终端执行如下: 1 初始化 Git 仓库(如果尚未初始化) git init 2 添加文件到 Git 仓库 git add . 3 使用 git commit 命令来提交你的更改。确保在提交时加上一个有用的消息。 git commit -m "备注信息" 4 …...
DeepSeek 赋能智慧能源:微电网优化调度的智能革新路径
目录 一、智慧能源微电网优化调度概述1.1 智慧能源微电网概念1.2 优化调度的重要性1.3 目前面临的挑战 二、DeepSeek 技术探秘2.1 DeepSeek 技术原理2.2 DeepSeek 独特优势2.3 DeepSeek 在 AI 领域地位 三、DeepSeek 在微电网优化调度中的应用剖析3.1 数据处理与分析3.2 预测与…...
【Linux】C语言执行shell指令
在C语言中执行Shell指令 在C语言中,有几种方法可以执行Shell指令: 1. 使用system()函数 这是最简单的方法,包含在stdlib.h头文件中: #include <stdlib.h>int main() {system("ls -l"); // 执行ls -l命令retu…...

2.Vue编写一个app
1.src中重要的组成 1.1main.ts // 引入createApp用于创建应用 import { createApp } from "vue"; // 引用App根组件 import App from ./App.vue;createApp(App).mount(#app)1.2 App.vue 其中要写三种标签 <template> <!--html--> </template>…...

SpringTask-03.入门案例
一.入门案例 启动类: package com.sky;import lombok.extern.slf4j.Slf4j; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cache.annotation.EnableCach…...

JVM虚拟机:内存结构、垃圾回收、性能优化
1、JVM虚拟机的简介 Java 虚拟机(Java Virtual Machine 简称:JVM)是运行所有 Java 程序的抽象计算机,是 Java 语言的运行环境,实现了 Java 程序的跨平台特性。JVM 屏蔽了与具体操作系统平台相关的信息,使得 Java 程序只需生成在 JVM 上运行的目标代码(字节码),就可以…...

C/C++ 中附加包含目录、附加库目录与附加依赖项详解
在 C/C 编程的编译和链接过程中,附加包含目录、附加库目录和附加依赖项是三个至关重要的设置,它们相互配合,确保程序能够正确引用外部资源并顺利构建。虽然在学习过程中,这些概念容易让人混淆,但深入理解它们的作用和联…...
pycharm 设置环境出错
pycharm 设置环境出错 pycharm 新建项目,设置虚拟环境,出错 pycharm 出错 Cannot open Local Failed to start [powershell.exe, -NoExit, -ExecutionPolicy, Bypass, -File, C:\Program Files\JetBrains\PyCharm 2024.1.3\plugins\terminal\shell-int…...

MySQL的pymysql操作
本章是MySQL的最后一章,MySQL到此完结,下一站Hadoop!!! 这章很简单,完整代码在最后,详细讲解之前python课程里面也有,感兴趣的可以往前找一下 一、查询操作 我们需要打开pycharm …...