当前位置: 首页 > news >正文

整数线性规划求解工具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 10
floor((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&#xff0c;我们可以对模型进行自动的调度&#xff0c;循环优化等。 编译 ISL,Integer Set Library 版本0.22.1&#xff0c;http://isl.gforge.inria.fr/ README关于…...

SystemC的调度器

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

SpringBoot、SpringCloud 版本查看

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

AI Chat 设计模式:12. 享元模式

本文是该系列的第十二篇&#xff0c;采用问答式的方式展开&#xff0c;问题由我提出&#xff0c;答案由 Chat AI 作出&#xff0c;灰色背景的文字则主要是我的一些思考和补充。 问题列表 Q.1 给我介绍一下享元模式A.1Q.2 也就是说&#xff0c;其实共享的是对象的内部状态&…...

Spring mvc:SpringServletContainerInitializer

SpringServletContainerInitializer实现了Servlet3.0规范中定义的ServletContainerInitializer&#xff1a; public interface ServletContainerInitializer {void onStartup(Set<Class<?>> c, ServletContext ctx) throws ServletException; }SpringServletCont…...

微信小程序中的全局数据共享(状态管理)使用介绍

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

LLM - LLama 模型读取报错 TypeError: not a string

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

2023年08月在线IDE流行度最新排名

点击查看最新在线IDE流行度最新排名&#xff08;每月更新&#xff09; 2023年08月在线IDE流行度最新排名 TOP 在线IDE排名是通过分析在线ide名称在谷歌上被搜索的频率而创建的 在线IDE被搜索的次数越多&#xff0c;人们就会认为它越受欢迎。原始数据来自谷歌Trends 如果您相…...

k8s的架构

简介 一个 K8s 系统&#xff0c;通常称为一个 K8s 集群&#xff0c;集群主要包括两个部分 一个 Master 节点&#xff08;主节点&#xff09; 一群 Node 节点&#xff08;计算节点&#xff09; 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、弱化次要元素 对于可以弱化的元素&#xff0c…...

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前端转正工作总结&#xff08;篇1&#xff09; 来到__有限公司已经三个月了&#xff0c;目前的工作是前端开发&#xff0c;我是一名应届毕业生&#xff0c;之前没有过工作经验&#xff0c;在刚来到__这个大家庭的时候&#xff0c;我就被这里的工作气氛深深地吸引&#xff0…...

P1144 最短路计数

最短路计数 题目描述 给出一个 N N N 个顶点 M M M 条边的无向无权图&#xff0c;顶点编号为 1 ∼ N 1\sim N 1∼N。问从顶点 1 1 1 开始&#xff0c;到其他每个点的最短路有几条。 输入格式 第一行包含 2 2 2 个正整数 N , M N,M N,M&#xff0c;为图的顶点数与边数…...

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 安井食品集团股份有限公司 招聘岗位&#xff1a;网络工程师 职责描述&#xff1a; 1.负责集团组网的网络规划、实施、维护工作&#xff1b; 2.负责公司局域网的网络规划、实施、维护工作&#xff1b; 3.负责公司企业安全系统规划、实施、维护工作&#xff1b; 4、负责公…...

小程序商品如何设置限购

限购是一种常用的小程序商品销售策略&#xff0c;可以帮助商家提高销售额、控制库存和增加用户的购买欲望。那么&#xff0c;小程序产品怎么设置限购呢&#xff1f;下面将为您详细介绍。 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 &#xff08;Message Queuing Telemetry Transport&#xff09;消息队列遥测传输协议&#xff0c;是一种基于发布/订阅&#xff08;publish/subscribe&#xff09;模式的"轻量级"通讯协议&#xff0c;该协议构建于TCP/IP协议上&#xff0c;由IBM在1999年发布。M…...

多云管理“拦路虎”:深入解析网络互联、身份同步与成本可视化的技术复杂度​

一、引言&#xff1a;多云环境的技术复杂性本质​​ 企业采用多云策略已从技术选型升维至生存刚需。当业务系统分散部署在多个云平台时&#xff0c;​​基础设施的技术债呈现指数级积累​​。网络连接、身份认证、成本管理这三大核心挑战相互嵌套&#xff1a;跨云网络构建数据…...

vscode里如何用git

打开vs终端执行如下&#xff1a; 1 初始化 Git 仓库&#xff08;如果尚未初始化&#xff09; 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语言中&#xff0c;有几种方法可以执行Shell指令&#xff1a; 1. 使用system()函数 这是最简单的方法&#xff0c;包含在stdlib.h头文件中&#xff1a; #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.入门案例

一.入门案例 启动类&#xff1a; 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 编程的编译和链接过程中&#xff0c;附加包含目录、附加库目录和附加依赖项是三个至关重要的设置&#xff0c;它们相互配合&#xff0c;确保程序能够正确引用外部资源并顺利构建。虽然在学习过程中&#xff0c;这些概念容易让人混淆&#xff0c;但深入理解它们的作用和联…...

pycharm 设置环境出错

pycharm 设置环境出错 pycharm 新建项目&#xff0c;设置虚拟环境&#xff0c;出错 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的最后一章&#xff0c;MySQL到此完结&#xff0c;下一站Hadoop&#xff01;&#xff01;&#xff01; 这章很简单&#xff0c;完整代码在最后&#xff0c;详细讲解之前python课程里面也有&#xff0c;感兴趣的可以往前找一下 一、查询操作 我们需要打开pycharm …...