/*zw: read the transformation function from .scop file*/ char* candl_program_read_scop_transform(FILE* file){ scoplib_scop_p scop; scop = scoplib_scop_read(file); char* candl_opts = scoplib_scop_tag_content(scop, "<candl>", "</candl>"); scoplib_scop_free(scop); if (!candl_opts) return NULL; char* transformation = scoplib_scop_tag_content_from_string(candl_opts, "<Transformation>", "</Transformation>"); free (candl_opts); if (! transformation) return NULL; else return transformation; }
/** * scoplib_scop_read function: * This function reads a scoplib_scop_t structure from an input stream * (possibly stdin) corresponding to a scoplib SCoP dump. * \param file The input stream */ scoplib_scop_p scoplib_scop_read(FILE* file) { char tmpbuff[SCOPLIB_MAX_STRING]; scoplib_scop_p scop = NULL; scoplib_statement_p stmt = NULL; scoplib_statement_p prev = NULL; int nb_statements; char** tmp; int i; char* content; if (file == NULL) return NULL; scop = scoplib_scop_malloc(); /* Backup the arrays of the program. Buffer is reajustable. */ int nb_arr = SCOPLIB_MAX_STRING; char** arrays = (char**) malloc (sizeof(char*) * nb_arr); for (i = 0; i < nb_arr; ++i) arrays[i] = NULL; /* Ensure the file is a .scop. */ tmp = scoplib_scop_read_strings(file, 1); if (strcmp(*tmp, "SCoP")) { fprintf(stderr, "[Scoplib] Error. The file is not a .scop\n"); exit (1); } free(*tmp); free(tmp); /* Read the language. */ char** language = scoplib_scop_read_strings(file, 1); if (strcmp(*language, "C") && strcmp(*language, "JAVA") && strcmp(*language, "C#")) { fprintf(stderr, "[Scoplib] Error. The language is not recognized\n"); exit (1); } /* language is not used so far. */ free(*language); free(language); /* Read the context. */ scop->context = scoplib_matrix_read (file); scop->nb_parameters = scop->context->NbColumns - 2; /* Read the parameter names, if any. */ if (scoplib_scop_read_int(file, NULL) > 0) scop->parameters = scoplib_scop_read_strings (file, scop->nb_parameters); else scop->parameters = scoplib_scop_generate_names("M", scop->nb_parameters); /* Read the number of statements. */ nb_statements = scoplib_scop_read_int (file, NULL); for (i = 0; i < nb_statements; ++i) { /* Read each statement. */ stmt = scoplib_statement_read (file, scop->nb_parameters, &arrays, &nb_arr); if (scop->statement == NULL) scop->statement = stmt; else prev->next = stmt; prev = stmt; } /* Read the remainder of the file, and store it in the optiontags field. */ /* Skip blank lines. */ while (! feof(file) && (fgets(tmpbuff, SCOPLIB_MAX_STRING, file) == 0 || tmpbuff[0] == '#' || isspace(tmpbuff[0]) || tmpbuff[0] != '<')) ; /* Store the remainder of the file, if any. */ if (tmpbuff[0]) { int count = strlen(tmpbuff); int pos = 0; int bufs = SCOPLIB_MAX_STRING; scop->optiontags = (char*) malloc(bufs * sizeof(char)); do { scop->optiontags = (char*) realloc (scop->optiontags, (bufs += count) * sizeof(char)); for (i = 0; i < count; ++i) scop->optiontags[pos++] = tmpbuff[i]; } while ((count = fread(tmpbuff, sizeof(char), SCOPLIB_MAX_STRING, file)) > 0); } /* Count the number of referenced arrays/variables. */ scop->nb_arrays = 0; for (stmt = scop->statement; stmt; stmt = stmt->next) { if (stmt->read) for (i = 0; i < stmt->read->NbRows; ++i) if (scop->nb_arrays < SCOPVAL_get_si(stmt->read->p[i][0])) scop->nb_arrays = SCOPVAL_get_si(stmt->read->p[i][0]); if (stmt->write) for (i = 0; i < stmt->write->NbRows; ++i) if (scop->nb_arrays < SCOPVAL_get_si(stmt->write->p[i][0])) scop->nb_arrays = SCOPVAL_get_si(stmt->write->p[i][0]); } /* Allocate the array names array. */ scop->arrays = (char**) malloc(sizeof(char*) * (scop->nb_arrays + 1)); for (i = 0; i < scop->nb_arrays; ++i) scop->arrays[i] = NULL; /* Populate the array list with referenced in the <array> tag, if any. */ if ((content = scoplib_scop_tag_content(scop, "<arrays>", "</arrays>"))) { char* start = content; int n_arr = scoplib_scop_read_int(NULL, &content); char buff2[SCOPLIB_MAX_STRING]; int idx_array; i = 0; while (n_arr--) { /* Skip blank or commented lines. */ while (*content == '#' || *content == '\n') { for (; *content != '\n'; ++content) ; ++content; } /* Get the variable id. */ for (i = 0; *content && ! isspace(*content); ++i, ++content) buff2[i] = *content; buff2[i] = '\0'; sscanf (buff2, "%d", &idx_array); /* Get the variable name. */ while (*content && isspace(*content)) ++content; for (i = 0; *content && ! isspace(*content); ++i, ++content) buff2[i] = *content; buff2[i] = '\0'; /* array is in 0-basis. */ if (arrays[idx_array - 1]) free(arrays[idx_array - 1]); arrays[idx_array - 1] = strdup(buff2); /* Go to the end of line. */ while (*content && *content != '\n') ++content; } content = start; } /* Fill the array of array names. */ char** tmparrays = scoplib_scop_generate_names("var", scop->nb_arrays); for (i = 0; i < scop->nb_arrays; ++i) { if (arrays[i] == NULL || arrays[i][0] == '\0') { /* Use a generated name in case no array name was parsed. */ scop->arrays[i] = tmparrays[i]; if (arrays[i]) free(arrays[i]); } else { /* Use the parsed array name. */ scop->arrays[i] = arrays[i]; free(tmparrays[i]); } } scop->arrays[i] = NULL; free(arrays); free(tmparrays); return scop; }
static void scoplib_scop_print_dot_scop_(FILE * file, scoplib_scop_p scop, int castle, int arraystag,int symboltable) { int i; if (castle) { fprintf(file,"# \n"); fprintf(file,"# <| \n"); fprintf(file,"# A \n"); fprintf(file,"# /.\\ \n"); fprintf(file,"# <| [\"\"M# \n"); fprintf(file,"# A | # Clan McCloog Castle \n"); fprintf(file,"# /.\\ [\"\"M# [File generated by ScopLib"); fprintf(file," %s %s bits]\n",SCOPLIB_RELEASE,SCOPLIB_VERSION); fprintf(file,"# [\"\"M# | # U\"U#U \n"); fprintf(file,"# | # | # \\ .:/ \n"); fprintf(file,"# | # | #___| # \n"); fprintf(file,"# | \"--' .-\" \n"); fprintf(file,"# |\"-\"-\"-\"-\"-#-#-## \n"); fprintf(file,"# | # ## ###### \n"); fprintf(file,"# \\ .::::'/ \n"); fprintf(file,"# \\ ::::'/ \n"); fprintf(file,"# :8a| # # ## \n"); fprintf(file,"# ::88a ### \n"); fprintf(file,"# ::::888a 8a ##::. \n"); fprintf(file,"# ::::::888a88a[]:::: \n"); fprintf(file,"# :::::::::SUNDOGa8a::::. .. \n"); fprintf(file,"# :::::8::::888:Y8888:::::::::... \n"); fprintf(file,"#::':::88::::888::Y88a______________________________"); fprintf(file,"________________________\n"); fprintf(file,"#:: ::::88a::::88a:Y88a "); fprintf(file," __---__-- __\n"); fprintf(file,"#' .: ::Y88a:::::8a:Y88a "); fprintf(file,"__----_-- -------_-__\n"); fprintf(file,"# :' ::::8P::::::::::88aa. _ _- -"); fprintf(file,"- --_ --- __ --- __--\n"); fprintf(file,"#.:: :::::::::::::::::::Y88as88a...s88aa.\n"); } else { fprintf(file,"# [File generated by ScopLib %s %s bits]\n", SCOPLIB_RELEASE,SCOPLIB_VERSION); } fprintf(file,"\n"); fprintf(file,"SCoP\n"); fprintf(file,"\n"); fprintf(file,"# =============================================== Global\n"); fprintf(file,"# Language\n"); fprintf(file,"C\n"); fprintf(file,"\n"); fprintf(file,"# Context\n"); scoplib_matrix_print_dot_scop(file,scop->context,SCOPLIB_TYPE_DOMAIN, 0,NULL, scop->nb_parameters,scop->parameters, scop->nb_arrays,scop->arrays); fprintf(file,"\n"); if (scop->nb_parameters > 0) { fprintf(file,"# Parameter names are provided\n"); fprintf(file,"1\n"); fprintf(file,"# Parameter names\n"); for (i = 0; i < scop->nb_parameters; i++) fprintf(file,"%s ",scop->parameters[i]); fprintf(file,"\n"); fprintf(file,"\n"); } else { fprintf(file,"# Parameter names are not provided\n"); fprintf(file,"0\n"); fprintf(file,"\n"); } fprintf(file,"# Number of statements\n"); fprintf(file,"%d\n",scoplib_statement_number(scop->statement)); fprintf(file,"\n"); scoplib_statement_print_dot_scop(file,scop->statement, scop->nb_parameters,scop->parameters, scop->nb_arrays,scop->arrays); fprintf(file,"# =============================================== Options\n"); if (scop->optiontags) fprintf(file, "%s", scop->optiontags); if (arraystag) { /* If the <array> tag is present in the option tags, don't dump it. */ char* content = scoplib_scop_tag_content (scop, "<arrays>", "</arrays>"); if (! content) { /* It isn't, so dump the list of arrays. */ fprintf(file, "\n<arrays>\n"); fprintf(file, "%d\n", scop->nb_arrays); for (i = 0; i < scop->nb_arrays; ++i) fprintf(file, "%d %s\n", i + 1, scop->arrays[i]); fprintf(file, "</arrays>\n"); } else free(content); } if(symboltable) { fprintf(file,"\n<symbol-table>\n"); scoplib_symbol_print_dot_scop(file,scop->symbol_table,scop->nb_parameters, scop->parameters,scop->nb_arrays,scop->arrays); fprintf(file,"</symbol-table>\n"); } }
int main(int argc, char *argv[]) { int i; FILE *src_fp; int option; int option_index = 0; char *srcFileName; FILE *cloogfp, *outfp; if (argc <= 1) { usage_message(); return 1; } options = pluto_options_alloc(); const struct option pluto_options[] = { {"tile", no_argument, &options->tile, 1}, {"notile", no_argument, &options->tile, 0}, {"intratileopt", no_argument, &options->intratileopt, 1}, {"debug", no_argument, &options->debug, true}, {"moredebug", no_argument, &options->moredebug, true}, {"rar", no_argument, &options->rar, 1}, {"identity", no_argument, &options->identity, 1}, {"nofuse", no_argument, &options->fuse, NO_FUSE}, {"maxfuse", no_argument, &options->fuse, MAXIMAL_FUSE}, {"smartfuse", no_argument, &options->fuse, SMART_FUSE}, {"parallel", no_argument, &options->parallel, 1}, {"parallelize", no_argument, &options->parallel, 1}, {"innerpar", no_argument, &options->innerpar, 1}, {"unroll", no_argument, &options->unroll, 1}, {"nounroll", no_argument, &options->unroll, 0}, {"polyunroll", no_argument, &options->polyunroll, 1}, {"bee", no_argument, &options->bee, 1}, {"ufactor", required_argument, 0, 'u'}, {"prevector", no_argument, &options->prevector, 1}, {"noprevector", no_argument, &options->prevector, 0}, {"context", required_argument, 0, 'c'}, {"cloogf", required_argument, 0, 'F'}, {"cloogl", required_argument, 0, 'L'}, {"cloogsh", no_argument, &options->cloogsh, 1}, {"nocloogbacktrack", no_argument, &options->cloogbacktrack, 0}, {"forceparallel", required_argument, 0, 'p'}, {"ft", required_argument, 0, 'f'}, {"lt", required_argument, 0, 'l'}, {"multipipe", no_argument, &options->multipipe, 1}, {"l2tile", no_argument, &options->l2tile, 1}, {"version", no_argument, 0, 'v'}, {"help", no_argument, 0, 'h'}, {"indent", no_argument, 0, 'i'}, {"silent", no_argument, &options->silent, 1}, {"lastwriter", no_argument, &options->lastwriter, 1}, {"nobound", no_argument, &options->nobound, 1}, {"scalpriv", no_argument, &options->scalpriv, 1}, {"isldep", no_argument, &options->isldep, 1}, {"isldepcompact", no_argument, &options->isldepcompact, 1}, {"readscoplib", no_argument, &options->readscoplib, 1}, {"islsolve", no_argument, &options->islsolve, 1}, {0, 0, 0, 0} }; /* Read command-line options */ while (1) { option = getopt_long(argc, argv, "bhiqvf:l:F:L:c:o:", pluto_options, &option_index); if (option == -1) { break; } switch (option) { case 0: break; case 'F': options->cloogf = atoi(optarg); break; case 'L': options->cloogl = atoi(optarg); break; case 'b': options->bee = 1; break; case 'c': options->context = atoi(optarg); break; case 'd': break; case 'f': options->ft = atoi(optarg); break; case 'g': break; case 'h': usage_message(); return 2; case 'i': /* Handled in polycc */ break; case 'l': options->lt = atoi(optarg); break; case 'm': break; case 'n': break; case 'o': options->out_file = strdup(optarg); break; case 'p': options->forceparallel = atoi(optarg); break; case 'q': options->silent = 1; break; case 's': break; case 'u': options->ufactor = atoi(optarg); break; case 'v': printf("PLUTO %s - An automatic parallelizer and locality optimizer\n\ Copyright (C) 2007--2008 Uday Kumar Bondhugula\n\ This is free software; see the source for copying conditions. There is NO\n\ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n", PLUTO_VERSION); pluto_options_free(options); return 3; default: usage_message(); pluto_options_free(options); return 4; } } if (optind <= argc-1) { srcFileName = alloca(strlen(argv[optind])+1); strcpy(srcFileName, argv[optind]); }else{ /* No non-option argument was specified */ usage_message(); pluto_options_free(options); return 5; } src_fp = fopen(srcFileName, "r"); if (!src_fp) { fprintf(stderr, "pluto: error opening source file: '%s'\n", srcFileName); pluto_options_free(options); return 6; } /* Extract polyhedral representation from input program */ scoplib_scop_p scop; clan_options_p clanOptions = clan_options_malloc(); if (options->readscoplib) scop = scoplib_scop_read(src_fp); else scop = clan_scop_extract(src_fp, clanOptions); if (!scop || !scop->statement) { fprintf(stderr, "Error extracting polyhedra from source file: \'%s'\n", srcFileName); pluto_options_free(options); return 7; } FILE *srcfp = fopen(".srcfilename", "w"); if (srcfp) { fprintf(srcfp, "%s\n", srcFileName); fclose(srcfp); } /* IF_DEBUG(clan_scop_print_dot_scop(stdout, scop, clanOptions)); */ /* Convert clan scop to Pluto program */ PlutoProg *prog = scop_to_pluto_prog(scop, options); clan_options_free(clanOptions); /* Backup irregular program portion in .scop. */ char* irroption = scoplib_scop_tag_content(scop, "<irregular>", "</irregular>"); IF_DEBUG2(pluto_deps_print(stdout, prog)); IF_DEBUG2(pluto_stmts_print(stdout, prog->stmts, prog->nstmts)); int dim_sum=0; for (i=0; i<prog->nstmts; i++) { dim_sum += prog->stmts[i]->dim; } /* Make options consistent */ if (options->multipipe == 1 && options->parallel == 0) { fprintf(stdout, "Warning: multipipe needs parallel to be on; turning on parallel\n"); options->parallel = 1; } /* Disable pre-vectorization if tile is not on */ if (options->tile == 0 && options->prevector == 1) { /* If code will not be tiled, pre-vectorization does not make * sense */ if (!options->silent) { fprintf(stdout, "[Pluto] Warning: pre-vectorization does not fit (--tile is off)\n"); } options->prevector = 0; } if (!options->silent) { fprintf(stdout, "[Pluto] Number of statements: %d\n", prog->nstmts); fprintf(stdout, "[Pluto] Total number of loops: %d\n", dim_sum); fprintf(stdout, "[Pluto] Number of deps: %d\n", prog->ndeps); fprintf(stdout, "[Pluto] Maximum domain dimensionality: %d\n", prog->nvar); fprintf(stdout, "[Pluto] Number of parameters: %d\n", prog->npar); } /* Auto transformation */ if (!options->identity) { pluto_auto_transform(prog); } pluto_detect_transformation_properties(prog); if (!options->silent) { fprintf(stdout, "[Pluto] Affine transformations [<iter coeff's> <const>]\n\n"); /* Print out transformations */ pluto_transformations_pretty_print(prog); pluto_print_hyperplane_properties(prog); } if (options->tile) { pluto_tile(prog); }else{ if (options->intratileopt) { int retval = pluto_intra_tile_optimize(prog, 0); if (retval) { /* Detect properties again */ pluto_detect_transformation_properties(prog); if (!options->silent) { printf("[Pluto] after intra tile opt\n"); pluto_transformations_pretty_print(prog); } } } } if (options->parallel && !options->tile && !options->identity) { /* Obtain wavefront/pipelined parallelization by skewing if * necessary */ int nbands; Band **bands; bands = pluto_get_outermost_permutable_bands(prog, &nbands); bool retval = create_tile_schedule(prog, bands, nbands); pluto_bands_free(bands, nbands); /* If the user hasn't supplied --tile and there is only pipelined * parallelism, we will warn the user */ if (retval) { printf("[Pluto] WARNING: pipelined parallelism exists and --tile is not used.\n"); printf("use --tile for better parallelization \n"); IF_DEBUG(fprintf(stdout, "[Pluto] After skewing:\n");); IF_DEBUG(pluto_transformations_pretty_print(prog););