Exemplo n.º 1
0
/* 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);
}
Exemplo n.º 2
0
/* 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;

}
Exemplo n.º 3
0
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");
}
Exemplo n.º 4
0
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;
}
Exemplo n.º 5
0
/* 
 * 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);
}
Exemplo n.º 6
0
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;
}
Exemplo n.º 7
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;
}
Exemplo n.º 8
0
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);
}
Exemplo n.º 9
0
/* 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;
}
Exemplo n.º 10
0
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;
}
Exemplo n.º 11
0
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;
}
Exemplo n.º 13
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);
	}
}
Exemplo n.º 14
0
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;
}
Exemplo n.º 15
0
/* 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;
}
Exemplo n.º 16
0
__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;
}
Exemplo n.º 17
0
/* 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;
}
Exemplo n.º 18
0
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;
}
Exemplo n.º 19
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);
}
Exemplo n.º 20
0
/* 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;
}
Exemplo n.º 21
0
/* 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;
}