/* Print a statement for copying an array to or from the device, * or for initializing or clearing the device. * The statement identifier of a copying node is called * "to_device_<array name>" or "from_device_<array name>" and * its user pointer points to the gpu_array_info of the array * that needs to be copied. * The node for initializing the device is called "init_device". * The node for clearing the device is called "clear_device". * * Extract the array (if any) from the identifier and call * init_device, clear_device, copy_array_to_device or copy_array_from_device. */ static __isl_give isl_printer *print_device_node(__isl_take isl_printer *p, __isl_keep isl_ast_node *node, struct gpu_prog *prog) { isl_ast_expr *expr, *arg; isl_id *id; const char *name; struct gpu_array_info *array; expr = isl_ast_node_user_get_expr(node); arg = isl_ast_expr_get_op_arg(expr, 0); id = isl_ast_expr_get_id(arg); name = isl_id_get_name(id); array = isl_id_get_user(id); isl_id_free(id); isl_ast_expr_free(arg); isl_ast_expr_free(expr); if (!name) return isl_printer_free(p); if (!strcmp(name, "init_device")) return init_device(p, prog); if (!strcmp(name, "clear_device")) return clear_device(p, prog); if (!array) return isl_printer_free(p); if (!prefixcmp(name, "to_device")) return copy_array_to_device(p, array); else return copy_array_from_device(p, array); }
/* Print the header of the given kernel to both gen->cuda.kernel_h * and gen->cuda.kernel_c. */ static void print_kernel_headers(struct gpu_prog *prog, struct ppcg_kernel *kernel, struct cuda_info *cuda) { isl_printer *p; p = isl_printer_to_file(prog->ctx, cuda->kernel_h); p = isl_printer_set_output_format(p, ISL_FORMAT_C); p = isl_printer_start_line(p); p = isl_printer_end_line(p); p = print_kernel_header(p, prog, kernel); p = isl_printer_print_str(p, ";"); p = isl_printer_end_line(p); isl_printer_free(p); p = isl_printer_to_file(prog->ctx, cuda->kernel_c); p = isl_printer_set_output_format(p, ISL_FORMAT_C); p = print_kernel_header(p, prog, kernel); p = isl_printer_end_line(p); isl_printer_free(p); //isl_printer *p; }
static void print_kernel(struct gpu_prog *prog, struct ppcg_kernel *kernel, struct cuda_info *cuda) { isl_ctx *ctx = isl_ast_node_get_ctx(kernel->tree); isl_ast_print_options *print_options; isl_printer *p; print_kernel_headers(prog, kernel, cuda); fprintf(cuda->kernel_c, "{\n"); print_kernel_iterators(cuda->kernel_c, kernel); p = isl_printer_to_file(ctx, cuda->kernel_c); p = isl_printer_set_output_format(p, ISL_FORMAT_C); p = isl_printer_indent(p, 4); p = print_kernel_vars(p, kernel); p = isl_printer_end_line(p); p = ppcg_set_macro_names(p); p = gpu_print_macros(p, kernel->tree); //p = print_surface_read_to_temp(p, kernel); print_options = isl_ast_print_options_alloc(ctx); print_options = isl_ast_print_options_set_print_user(print_options, &print_kernel_stmt, NULL); p = isl_ast_node_print(kernel->tree, p, print_options); isl_printer_free(p); fprintf(cuda->kernel_c, "}\n"); }
int main(int argc, char **argv) { isl_ctx *ctx; isl_printer *p; isl_schedule_constraints *sc; isl_schedule *schedule; struct isl_options *options; options = isl_options_new_with_defaults(); argc = isl_options_parse(options, argc, argv, ISL_ARG_ALL); ctx = isl_ctx_alloc_with_options(&isl_options_args, options); sc = isl_schedule_constraints_read_from_file(ctx, stdin); schedule = isl_schedule_constraints_compute_schedule(sc); p = isl_printer_to_file(ctx, stdout); p = isl_printer_set_yaml_style(p, ISL_YAML_STYLE_BLOCK); p = isl_printer_print_schedule(p, schedule); isl_printer_free(p); isl_schedule_free(schedule); isl_ctx_free(ctx); return p ? EXIT_SUCCESS : EXIT_FAILURE; }
/* * Each test case should name statements S_0, S_1, ... */ int test2() { printf("TEST 2\n"); isl_ctx *ctx = isl_ctx_alloc(); isl_union_set *domains = isl_union_set_read_from_str(ctx, "[p_0, p_1, p_2, p_3, p_4, p_5, p_7] -> { S_1[i0, i1] : i0 >= 0 and i0 <= p_0 and i1 >= 0 and i1 <= p_3 and p_2 >= 0; S_0[i0] : i0 >= 0 and i0 <= p_0}"); isl_union_map *deps = isl_union_map_read_from_str(ctx, "[p_0, p_1, p_2, p_3, p_4, p_5, p_7] -> { S_0[i0] -> S_1[o0, o1] : (exists (e0 = [(p_7)/8]: 8o1 = -p_5 + p_7 + 8192i0 - 8192o0 and 8e0 = p_7 and i0 >= 0 and o0 <= p_0 and 8192o0 >= -8p_3 - p_5 + p_7 + 8192i0 and 8192o0 <= -p_5 + p_7 + 8192i0 and p_2 >= 0 and o0 >= 1 + i0)); S_1[i0, i1] -> S_0[o0] : (exists (e0 = [(p_1)/8], e1 = [(p_4)/8], e2 = [(-p_1 + p_7)/8184]: 8192o0 = p_5 - p_7 + 8192i0 + 8i1 and 8e0 = p_1 and 8e1 = p_4 and 8184e2 = -p_1 + p_7 and i1 >= 0 and 8i1 <= 8192p_0 - p_5 + p_7 - 8192i0 and 8184i1 >= 1024 + 1024p_1 - 1023p_5 - p_7 - 8380416i0 and p_2 >= 0 and p_7 <= -1 + p_5 and 8i1 >= 1 + 8p_3 + p_4 - p_5 - 8192i0 and i1 <= p_3 and i0 >= 0 and 8i1 >= 8192 - p_5 + p_7))}"); isl_union_map *schedule = pluto_schedule(domains, deps, options); if (schedule) { isl_printer *printer = isl_printer_to_file(ctx, stdout); isl_printer_print_union_map(printer, schedule); printf("\n"); isl_printer_free(printer); // Check if the schedule can be applied to the domain. domains = isl_union_set_apply(domains, schedule); }else{ printf("No schedule\n"); } isl_union_set_free(domains); isl_union_map_free(deps); isl_ctx_free(ctx); }
int main(int argc, char **argv) { struct isl_ctx *ctx; struct isl_map *map; struct isl_options *options; isl_printer *p; int exact; options = isl_options_new_with_defaults(); assert(options); argc = isl_options_parse(options, argc, argv, ISL_ARG_ALL); ctx = isl_ctx_alloc_with_options(&isl_options_args, options); p = isl_printer_to_file(ctx, stdout); map = isl_map_read_from_file(ctx, stdin); map = isl_map_transitive_closure(map, &exact); if (!exact) p = isl_printer_print_str(p, "# NOT exact\n"); p = isl_printer_print_map(p, map); p = isl_printer_end_line(p); map = isl_map_compute_divs(map); map = isl_map_coalesce(map); p = isl_printer_print_str(p, "# coalesced\n"); p = isl_printer_print_map(p, map); p = isl_printer_end_line(p); isl_map_free(map); isl_printer_free(p); isl_ctx_free(ctx); return 0; }
isl_set *nfm_constraint_from_set(isl_ctx *ctx, nfm_constraint *constraints) { isl_printer *p; assert(ctx); assert(constraints); IF_DEBUG(fprintf(stdout, " Transforming a constraint into ISL set.\n")); p = isl_printer_to_str(ctx); p = isl_printer_print_pw_qpolynomial(p, constraints->constraint); char *str = isl_printer_get_str(p); IF_DEBUG(fprintf(stdout, " The input Qpolynomianl constraint: %s\n", str)); assert(str); /* Translate the qpolynomial into a map. */ char *set_str = (char *) malloc((strlen(str)+10)*sizeof(char)); strcpy(set_str, str); IF_DEBUG2(fprintf(stdout, " set_str=%s\n", set_str)); size_t pos_arrow = strcspn(str, ">"); set_str[pos_arrow-1] = ' '; set_str[pos_arrow] = ':'; IF_DEBUG2(fprintf(stdout, " set_str=%s\n", set_str)); size_t pos_colon = strcspn(&(str[pos_arrow+1]), ":"); if (strchr(&(str[pos_arrow+1]), ':') != NULL) { set_str[pos_arrow+1+pos_colon] = ' '; IF_DEBUG2(fprintf(stdout, " set_str=%s\n", set_str)); if (constraints->eq == 1) strcpy(&(set_str[pos_arrow+1+pos_colon]), " = 0 and "); else strcpy(&(set_str[pos_arrow+1+pos_colon]), " >= 0 and "); IF_DEBUG2(fprintf(stdout, " set_str=%s\n", set_str)); strncpy(&(set_str[pos_arrow+pos_colon+10]), &(str[pos_arrow+1+pos_colon+1]), strlen(str) - pos_arrow - pos_colon); IF_DEBUG2(fprintf(stdout, " set_str=%s\n", set_str)); } else { size_t pos_bracket = strcspn(str, "}"); set_str[pos_bracket] = ' '; if (constraints->eq == 1) strcat(&(set_str[pos_bracket]), " = 0 }"); else strcat(&(set_str[pos_bracket]), " >= 0 }"); } IF_DEBUG(fprintf(stdout, " The Qpolynomial translated into a set is: %s\n", set_str)); isl_set *set = isl_set_read_from_str(ctx, set_str); isl_printer_free(p); return set; }
void isl_id_dump(__isl_keep isl_id *id) { isl_printer *printer; if (!id) return; printer = isl_printer_to_file(isl_id_get_ctx(id), stderr); printer = isl_printer_print_id(printer, id); printer = isl_printer_end_line(printer); isl_printer_free(printer); }
/* Given a gpu_prog "prog" and the corresponding transformed AST * "tree", print the entire CUDA code to "p". * "types" collects the types for which a definition has already * been printed. */ static __isl_give isl_printer *print_cuda(__isl_take isl_printer *p, struct gpu_prog *prog, __isl_keep isl_ast_node *tree, struct gpu_types *types, void *user) { struct cuda_info *cuda = user; isl_printer *kernel; kernel = isl_printer_to_file(isl_printer_get_ctx(p), cuda->kernel_c); kernel = isl_printer_set_output_format(kernel, ISL_FORMAT_C); kernel = gpu_print_types(kernel, types, prog); isl_printer_free(kernel); if (!kernel) return isl_printer_free(p); texture_optimization(prog,tree); p = print_host_code(p, prog, tree, cuda); isl_printer *tp = isl_printer_to_file(isl_printer_get_ctx(p), cuda->kernel_h); tp = isl_printer_set_output_format(tp, ISL_FORMAT_C); print_texture_or_surface_decl(tp, prog); isl_printer_free(tp); printf("\n Clearing done"); fflush(stdout); // Clearing is_texture or is_surface required clear_texture_flags(prog); return p; }
static __isl_give isl_printer *str_print_indent(__isl_take isl_printer *p, int indent) { int i; if (p->buf_n + indent + 1 >= p->buf_size && grow_buf(p, indent)) goto error; for (i = 0; i < indent; ++i) p->buf[p->buf_n++] = ' '; return p; error: isl_printer_free(p); return NULL; }
static __isl_give isl_printer *str_print(__isl_take isl_printer *p, const char *s, int len) { if (p->buf_n + len + 1 >= p->buf_size && grow_buf(p, len)) goto error; memcpy(p->buf + p->buf_n, s, len); p->buf_n += len; p->buf[p->buf_n] = '\0'; return p; error: isl_printer_free(p); return NULL; }
int main(int argc, char **argv) { struct isl_ctx *ctx = isl_ctx_alloc(); struct isl_basic_set *bset; struct isl_vec *obj; struct isl_vec *sol; isl_int opt; unsigned dim; enum isl_lp_result res; isl_printer *p; isl_int_init(opt); bset = isl_basic_set_read_from_file(ctx, stdin); assert(bset); obj = isl_vec_read_from_file(ctx, stdin); assert(obj); dim = isl_basic_set_total_dim(bset); assert(obj->size >= dim && obj->size <= dim + 1); if (obj->size != dim + 1) obj = isl_vec_lin_to_aff(obj); else obj = vec_ror(obj); res = isl_basic_set_solve_ilp(bset, 0, obj->el, &opt, &sol); switch (res) { case isl_lp_error: fprintf(stderr, "error\n"); return -1; case isl_lp_empty: fprintf(stdout, "empty\n"); break; case isl_lp_unbounded: fprintf(stdout, "unbounded\n"); break; case isl_lp_ok: p = isl_printer_to_file(ctx, stdout); p = isl_printer_print_vec(p, sol); p = isl_printer_end_line(p); p = isl_printer_print_isl_int(p, opt); p = isl_printer_end_line(p); isl_printer_free(p); } isl_basic_set_free(bset); isl_vec_free(obj); isl_vec_free(sol); isl_ctx_free(ctx); isl_int_clear(opt); return 0; }
void isl_stream_error(struct isl_stream *s, struct isl_token *tok, char *msg) { int line = tok ? tok->line : s->line; int col = tok ? tok->col : s->col; fprintf(stderr, "syntax error (%d, %d): %s\n", line, col, msg); if (tok) { if (tok->type < 256) fprintf(stderr, "got '%c'\n", tok->type); else if (tok->type == ISL_TOKEN_IDENT) fprintf(stderr, "got ident '%s'\n", tok->u.s); else if (tok->is_keyword) fprintf(stderr, "got keyword '%s'\n", tok->u.s); else if (tok->type == ISL_TOKEN_VALUE) { fprintf(stderr, "got value '"); isl_int_print(stderr, tok->u.v, 0); fprintf(stderr, "'\n"); } else if (tok->type == ISL_TOKEN_MAP) { isl_printer *p; fprintf(stderr, "got map '"); p = isl_printer_to_file(s->ctx, stderr); p = isl_printer_print_map(p, tok->u.map); isl_printer_free(p); fprintf(stderr, "'\n"); } else if (tok->type == ISL_TOKEN_AFF) { isl_printer *p; fprintf(stderr, "got affine expression '"); p = isl_printer_to_file(s->ctx, stderr); p = isl_printer_print_pw_aff(p, tok->u.pwaff); isl_printer_free(p); fprintf(stderr, "'\n"); } else if (tok->u.s) fprintf(stderr, "got token '%s'\n", tok->u.s); else fprintf(stderr, "got token type %d\n", tok->type); } }
static __isl_give isl_printer *str_print_int(__isl_take isl_printer *p, int i) { int left = p->buf_size - p->buf_n; int need = snprintf(p->buf + p->buf_n, left, "%d", i); if (need >= left) { if (grow_buf(p, need)) goto error; left = p->buf_size - p->buf_n; need = snprintf(p->buf + p->buf_n, left, "%d", i); } p->buf_n += need; return p; error: isl_printer_free(p); return NULL; }
/* Set the arguments of the OpenCL kernel by printing a call to the OpenCL * clSetKernelArg() function for each kernel argument. */ static __isl_give isl_printer *opencl_set_kernel_arguments( __isl_take isl_printer *p, struct gpu_prog *prog, struct ppcg_kernel *kernel) { int i, n, ro; unsigned nparam; isl_space *space; int arg_index = 0; for (i = 0; i < prog->n_array; ++i) { int required; required = ppcg_kernel_requires_array_argument(kernel, i); if (required < 0) return isl_printer_free(p); if (!required) continue; ro = gpu_array_is_read_only_scalar(&prog->array[i]); opencl_set_kernel_argument(p, kernel->id, prog->array[i].name, arg_index, ro); arg_index++; } space = isl_union_set_get_space(kernel->arrays); nparam = isl_space_dim(space, isl_dim_param); for (i = 0; i < nparam; ++i) { const char *name; name = isl_space_get_dim_name(space, isl_dim_param, i); opencl_set_kernel_argument(p, kernel->id, name, arg_index, 1); arg_index++; } isl_space_free(space); n = isl_space_dim(kernel->space, isl_dim_set); for (i = 0; i < n; ++i) { const char *name; name = isl_space_get_dim_name(kernel->space, isl_dim_set, i); opencl_set_kernel_argument(p, kernel->id, name, arg_index, 1); arg_index++; } return p; }
__isl_give isl_printer *isl_printer_print_id(__isl_take isl_printer *p, __isl_keep isl_id *id) { if (!id) goto error; if (id->name) p = isl_printer_print_str(p, id->name); if (id->user) { char buffer[50]; snprintf(buffer, sizeof(buffer), "@%p", id->user); p = isl_printer_print_str(p, buffer); } return p; error: isl_printer_free(p); return NULL; }
/* Transform the code in the file called "input" by replacing * all scops by corresponding OpenCL code. * The host code is written to "output" or a name derived from * "input" if "output" is NULL. * The kernel code is placed in separate files with names * derived from "output" or "input". * * We let generate_gpu do all the hard work and then let it call * us back for printing the AST in print_opencl. * * To prepare for this printing, we first open the output files * and we close them after generate_gpu has finished. */ int generate_opencl(isl_ctx *ctx, struct ppcg_options *options, const char *input, const char *output) { struct opencl_info opencl = { options, input, output }; int r; opencl.kprinter = isl_printer_to_str(ctx); r = opencl_open_files(&opencl); if (r >= 0) r = generate_gpu(ctx, input, opencl.host_c, options, &print_opencl, &opencl); if (opencl_close_files(&opencl) < 0) r = -1; isl_printer_free(opencl.kprinter); return r; }
int main(int argc, char **argv) { struct isl_ctx *ctx = isl_ctx_alloc(); struct isl_basic_set *bset; struct isl_vec *sample; isl_printer *p; bset = isl_basic_set_read_from_file(ctx, stdin); sample = isl_basic_set_sample_vec(isl_basic_set_copy(bset)); p = isl_printer_to_file(ctx, stdout); p = isl_printer_print_vec(p, sample); p = isl_printer_end_line(p); isl_printer_free(p); assert(sample); if (sample->size > 0) assert(isl_basic_set_contains(bset, sample)); isl_basic_set_free(bset); isl_vec_free(sample); isl_ctx_free(ctx); return 0; }
void test1() { isl_ctx *ctx = isl_ctx_alloc(); isl_union_set *domains = isl_union_set_read_from_str(ctx, "[n] -> {S_1[i0, i1] : i0 >= 0 and i0 <= 99 and i1 >= 0 and i1 <= 99; S_0[i0] : i0 >= 0 and i0 <= 99; S_2[i0] : i0 >= 0 and i0 <= 99 }"); isl_union_map *deps = isl_union_map_read_from_str(ctx, "[n] -> {S_1[i0, 99] -> S_0[1 + i0] : i0 >= 0 and i0 <= 98; S_1[i0, i1] -> S_1[i0, 1 + i1] : i0 >= 0 and i0 <= 99 and i1 >= 0 and i1 <= 98; S_1[i0, 99] -> S_1[1 + i0, 0] : i0 >= 0 and i0 <= 98; S_0[i0] -> S_1[i0, 0] : i0 >= 0 and i0 <= 99; S_2[i0] -> S_1[1 + i0, 0] : i0 >= 0 and i0 <= 98; S_0[i0] -> S_2[i0] : i0 >= 0 and i0 <= 99; S_1[i0, 99] -> S_2[i0] : i0 >= 0 and i0 <= 99 }"); isl_union_map *schedule = pluto_schedule(domains, deps, options); isl_printer *printer = isl_printer_to_file(ctx, stdout); isl_printer_print_union_map(printer, schedule); printf("\n"); isl_printer_free(printer); // Check if the schedule can be applied to the domain. domains = isl_union_set_apply(domains, schedule); isl_union_set_free(domains); isl_union_map_free(deps); isl_ctx_free(ctx); }
/* Given a gpu_prog "prog" and the corresponding transformed AST * "tree", print the entire OpenCL code to "p". */ static __isl_give isl_printer *print_opencl(__isl_take isl_printer *p, struct gpu_prog *prog, __isl_keep isl_ast_node *tree, struct gpu_types *types, void *user) { struct opencl_info *opencl = user; opencl->kprinter = isl_printer_set_output_format(opencl->kprinter, ISL_FORMAT_C); if (any_double_elements(prog)) opencl->kprinter = opencl_enable_double_support( opencl->kprinter); if (opencl->options->opencl_print_kernel_types) opencl->kprinter = gpu_print_types(opencl->kprinter, types, prog); if (!opencl->kprinter) return isl_printer_free(p); p = ppcg_start_block(p); p = opencl_print_host_macros(p); p = gpu_print_local_declarations(p, prog); p = opencl_declare_device_arrays(p, prog); p = opencl_setup(p, opencl->input, opencl); p = opencl_allocate_device_arrays(p, prog); p = opencl_print_host_code(p, prog, tree, opencl); p = opencl_release_device_arrays(p, prog); p = opencl_release_cl_objects(p, opencl); p = ppcg_end_block(p); return p; }
/* Print the arguments to a kernel declaration or call. If "types" is set, * then print a declaration (including the types of the arguments). * * The arguments are printed in the following order * - the arrays accessed by the kernel * - the parameters * - the host loop iterators */ static __isl_give isl_printer *print_kernel_arguments(__isl_take isl_printer *p, struct gpu_prog *prog, struct ppcg_kernel *kernel, int types) { int i, n; int first = 1; unsigned nparam; isl_space *space; const char *type; for (i = 0; i < prog->n_array; ++i) { int required; required = ppcg_kernel_requires_array_argument(kernel, i); if (required < 0) return isl_printer_free(p); if (!required) continue; if(!print_device_arrays_or_not(&prog->array[i])) continue; if (!first) p = isl_printer_print_str(p, ", "); if (types) p = gpu_array_info_print_declaration_argument(p, &prog->array[i], NULL); else p = gpu_array_info_print_call_argument(p, &prog->array[i]); first = 0; } space = isl_union_set_get_space(kernel->arrays); nparam = isl_space_dim(space, isl_dim_param); for (i = 0; i < nparam; ++i) { const char *name; name = isl_space_get_dim_name(space, isl_dim_param, i); if (!first) p = isl_printer_print_str(p, ", "); if (types) p = isl_printer_print_str(p, "int "); p = isl_printer_print_str(p, name); first = 0; } isl_space_free(space); n = isl_space_dim(kernel->space, isl_dim_set); type = isl_options_get_ast_iterator_type(prog->ctx); for (i = 0; i < n; ++i) { const char *name; if (!first) p = isl_printer_print_str(p, ", "); name = isl_space_get_dim_name(kernel->space, isl_dim_set, i); if (types) { p = isl_printer_print_str(p, type); p = isl_printer_print_str(p, " "); } p = isl_printer_print_str(p, name); first = 0; } return p; }