1)main函数在tool/main.cpp里面
2)结构体定义
PlutoContext *context = pluto_context_alloc();
PlutoOptions *options = context->options;
定义在pluto.h里面
struct plutoOptions {
}
typedef struct plutoOptions PlutoOptions;
PlutoOptions *pluto_options_alloc();
void pluto_options_free(PlutoOptions *);
typedef struct plutoContext {
PlutoOptions *options;
} PlutoContext;
PlutoContext *pluto_context_alloc();
void pluto_context_free(PlutoContext *context);
3)给各种函数疯狂赋值
#ifdef GLPK
{"glpk", no_argument, &options->glpk, 1},
#endif
#ifdef GUROBI
{"gurobi", no_argument, &options->gurobi, 1},
#endif
#if defined GLPK || defined GUROBI
{"lp", no_argument, &options->lp, 1},
{"dfp", no_argument, &options->dfp, 1},
{"ilp", no_argument, &options->ilp, 1},
{"lpcolor", no_argument, &options->lpcolour, 1},
{"clusterscc", no_argument, &options->scc_cluster, 1},
#endif
{"islsolve", no_argument, &options->islsolve, 1},
{"time", no_argument, &options->time, 1},
{0, 0, 0, 0}
4)
printf(
"PLUTO version %s - An automatic parallelizer and locality optimizer\n\
Copyright (C) 2007--2015 Uday 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);
5)选择用哪个库
/* isldep is the default */
if (!options->isldep && !options->candldep) {
options->isldep = 1;
}
if (options->lastwriter && options->candldep) {
printf("[pluto] ERROR: --lastwriter is only supported with --isldep\n");
pluto_options_free(options);
usage_message();
return 1;
}
if (options->second_level_tile && options->find_tile_sizes) {
printf("[pluto] ERROR: Automatic tile size selection is supported only for "
"one level of tiling\n");
pluto_options_free(options);
usage_message();
return 1;
}
6)读取输入文件:
/* Extract polyhedral representation from input program */
if (options->pet) {
// Extract using PET.
isl_ctx *pctx = isl_ctx_alloc_with_pet_options();
struct pet_scop *pscop =
pet_scop_extract_from_C_source(pctx, srcFileName, NULL);
}
} else {
// Extract polyhedral representation using Clan.
}
} else {
// Read from regular file.
}
使用PET或者CLan读取文件?这是啥玩意,输入是文件,输出是啥?
7)
结构体struct pet_scop在pet.h中,grep好像有点问题。
struct pet_scop {
pet_loc *loc;
isl_set *context;
isl_set *context_value;
isl_schedule *schedule;
int n_type;
struct pet_type **types;
int n_array;
struct pet_array **arrays;
int n_stmt;
struct pet_stmt **stmts;
int n_implication;
struct pet_implication **implications;
int n_independence;
struct pet_independence **independences;
};
typedef struct pet_scop pet_scop;
8)
这应该是真正转换的函数?
double t_start = rtclock();
prog = pet_to_pluto_prog(pscop, pctx, context);
t_d = rtclock() - t_start;
9)tool/pet_to_pluto.cpp
#include "pet_to_pluto.h"
#include "constraints.h"
#include "math_support.h"
#include "pluto/matrix.h"
#include "pluto/pluto.h"
#include "program.h"
#include "isl/flow.h"
#include "isl/id.h"
#include "isl/map.h"
#include "isl/mat.h"
#include "isl/set.h"
#include "isl/space.h"
#include "isl/union_map.h"
#include "isl/union_set.h"
#include "isl/val.h"
#include "pet.h"
/*
* Extract necessary information from pet_scop to create PlutoProg - a
* representation of the program sufficient to be used throughout Pluto.
* PlutoProg also includes dependences; uses isl.
*/
PlutoProg *pet_to_pluto_prog(struct pet_scop *pscop, isl_ctx *ctx,
PlutoContext *context) {
调用了很多isl的函数
10)
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);
}
11)
/* Auto transformation */
if (!options->identity) {
pluto_auto_transform(prog);
}
在lib/pluto.c中
/**
* Top-level automatic transformation algoritm. Returns 0 on success.
*
* All dependences are reset to unsatisfied before starting.
*
*/
int pluto_auto_transform(PlutoProg *prog) {
int i, j, s, nsols, depth;
/* The maximum number of linearly independent solutions needed across all
* statements */
int num_ind_sols_req;
PlutoContext *context = prog->context;
PlutoOptions *options = context->options;
pluto代码其实很复杂了。看懂都不容易。
12)依赖方向 ?
依赖分析?
pluto_compute_dep_directions(prog);
pluto_compute_dep_satisfaction(prog);
在lib/pluto.c中
/* Get the permutability constraints since a call to
* detect_transformation_properties with update dep satisfaction levels
* and we won't get the constraints we want */
void pluto_compute_dep_directions(PlutoProg *prog) {
int i, level;
Dep **deps = prog->deps;
for (i = 0; i < prog->ndeps; i++) {
if (deps[i]->dirvec != NULL) {
free(deps[i]->dirvec);
}
deps[i]->dirvec = (DepDir *)malloc(prog->num_hyperplanes * sizeof(DepDir));
for (level = 0; level < prog->num_hyperplanes; level++) {
deps[i]->dirvec[level] = get_dep_direction(deps[i], prog, level);
}
}
}
要看懂,需要对代码进行仔细的分析。
13)
/*
* Conservative but powerful enough: until a dependence has been completely
* satisfied (a level at which it is completely satisifed), a non-zero
* dependence component would set satvec for that level to one
*/
void pluto_compute_dep_satisfaction(PlutoProg *prog) {
int i, level;
PlutoContext *context = prog->context;
IF_DEBUG(printf("[pluto] pluto_compute_dep_satisfaction\n"););
pluto_dep_satisfaction_reset(prog);
for (i = 0; i < prog->num_hyperplanes; i++) {
dep_satisfaction_update(prog, i);
}
/* Create and set satisfaction vectors */
for (i = 0; i < prog->ndeps; i++) {
Dep *dep = prog->deps[i];
if (IS_RAR(dep->type))
continue;
if (dep->satvec)
free(dep->satvec);
dep->satvec = (int *)malloc(prog->num_hyperplanes * sizeof(int));
/* Direction vectors should be available */
assert(dep->dirvec != NULL);
for (level = 0; level < prog->num_hyperplanes; level++) {
if (dep->dirvec[level] != DEP_ZERO &&
(dep->satisfaction_level >= level || dep->satisfaction_level == -1)) {
dep->satvec[level] = 1;
} else {
dep->satvec[level] = 0;
}
}
}
}
也不容易,需要深入了解代码和原理。
一步一步,到底是怎么变换的。
14)
if (options->tile) {
pluto_tile(prog);
} else {
if (options->intratileopt) {
pluto_intra_tile_optimize(prog, 0);
}
}
pluto_tile在lib/tile.c中
/* Manipulates statement domain and transformation to tile scattering
* dimensions from firstD to lastD */
void pluto_tile_band(PlutoProg *prog, Band *band, int *tile_sizes) {
15)
最后输出一些信息
if (options->time && !options->silent) {
printf("\n[pluto] Timing statistics\n[pluto] SCoP extraction + dependence "
"analysis time: %0.6lfs\n",
t_d);
printf("[pluto] Auto-transformation time: %0.6lfs\n", t_t);
printf("[pluto] Tile size selection time: %0.6lfs\n", prog->tss_time);
if (options->dfp) {
printf("[pluto] \tFCG construction time: %0.6lfs\n",
prog->fcg_const_time);
printf("[pluto] \tFCG colouring time: %0.6lfs\n", prog->fcg_colour_time);
printf("[pluto] \tscaling + shifting time: %0.6lfs\n",
prog->fcg_dims_scale_time);
printf("[pluto] \tskew determination time: %0.6lfs\n", prog->skew_time);
}
printf("[pluto] \t\tTotal constraint solving time (LP/MIP/ILP) time: "
"%0.6lfs\n",
prog->mipTime);
printf("[pluto] Code generation time: %0.6lfs\n", t_c);
printf("[pluto] Other/Misc time: %0.6lfs\n", t_all - t_c - t_t - t_d);
printf("[pluto] Total time: %0.6lfs\n", t_all);
printf("[pluto] All times: %0.6lf %0.6lf %.6lf %.6lf\n", t_d, t_t, t_c,
t_all - t_c - t_t - t_d);
}
看得累死了,其实程序非常复杂了。只能一个一个函数看才行。