-
Notifications
You must be signed in to change notification settings - Fork 134
Tool User Tutorial
The purpose of this tutorial is to show user the basic components of running ROSE based tools. This tutorial will look at analysis and transformation tools.
The first step to running any ROSE based tool is to install ROSE core. Instructions on how to do this can be found on How to Set Up ROSE.
To build and install the tools navigate to ${ROSE_BUILD}/tools
and run make install
. This will run the install process for a few different tools including the ones this tutorial will cover.
You should now set your environment variables for search paths that include ROSE executables, ROSE tools, and shared libraries. When you ran make install
it placed everything in the install folder specified at configure time.
export ROSE_SRC=/path/to/rose/src/tree # example /data/rose/src
export ROSE_INSTALL=/path/to/rose/install/tree # example /data/rose/install
export PATH=${ROSE_INSTALL}/bin:${PATH}
export LD_LIBRARY_PATH=${ROSE_INSTALL}/lib:${LD_LIBRARY_PATH}
The analysis tool rajaChecker is a C++ source code analysis tool to detect some specialized code patterns.
The following command will run rajaChecker on some sample source files. The output will be saved to ~/rajaChecker-passed_files.txt
.
rajaChecker ${ROSE_SRC}/tools/tests/constDouble.cpp ${ROSE_SRC}/tools/tests/definedTwice.cpp -c
This command results in the following output.
------------------------
2019-09-26 13:34:37 52539
Processed File: Without Errors:/data/rose/src/tools/tests/constDouble.cpp
/data/rose/src/tools/tests/constDouble.cpp:Found a nodal accumulation loop at line:11 1st acc. stmt at line:13
Processed File: Without Errors:/data/rose/src/tools/tests/definedTwice.cpp
/data/rose/src/tools/tests/definedTwice.cpp:Found a nodal accumulation loop at line:14 1st acc. stmt at line:20
With ROSE acting as the frontend, options not used by the tool (like -c
) are passed to the backend compiler. For options used by the tool it will remove those option if nessesary when calling the backend compiler. Options that start with -rose:
are options for ROSE or the tool you are using, though some tools, like rajaChecker, use options that do not begin with -rose:
. The following command shows using an additional option to specify an output file to rajaChecker
.
rajaChecker -report=/data/output.txt ${ROSE_SRC}/tools/tests/constDouble.cpp ${ROSE_SRC}/tools/tests/definedTwice.cpp -c
A ROSE based tool acts like a compiler, so it can be easily integrated into most build systems. By setting CXX or CC to the ROSE tool, and adding any tool options, your build system should then run the tool on all files in the system.
export CXX=rose-c++
export CC=rose-cc
If you wanted to use rajaChecker on everything in the build system you could set CXX
as follows then run your build system.
export CXX="rajaChecker -report=/path/to/report"
The transformation tool moveDeclarationToInnermostScope will move variable declarations to their innermost possible used scopes.
You can run the tool with the following command line.
moveDeclarationToInnermostScope -c Test.cc
For an input file we will be using the following program named Test.cc.
#define REG register
void AccumulateForce(int *idxBound, int *idxList, int len, double *tmp, double *force){
//These declarations can be moved inside the loop
REG int ii ;
REG int jj ;
int count ;
int *list ;
int idx ;
double sum ;
for (ii=0; ii<len; ++ii) {
count = idxBound[ii+1] - idxBound[ii] ;
list = &idxList[idxBound[ii]] ;
sum = 0.0 ;
for (jj=0; jj<count; ++jj) {
idx = list[jj] ;
sum += tmp[idx] ;
}
force[ii] += sum ;
}
return ;
}
The transformed source code is written to a file with rose_
prepended to the original source file name, in this case rose_Test.cc
. Notice how following transformed code has moved all the declarations to be inside the scope of the loops.
#define REG register
void AccumulateForce(int *idxBound,int *idxList,int len,double *tmp,double *force)
{
//These declarations can be moved inside the loop
for (register int ii = 0; ii < len; ++ii) {
int count;
int *list;
double sum;
count = idxBound[ii + 1] - idxBound[ii];
list = &idxList[idxBound[ii]];
sum = 0.0;
for (register int jj = 0; jj < count; ++jj) {
int idx;
idx = list[jj];
sum += tmp[idx];
}
force[ii] += sum;
}
return ;
}
Functioning in the same way as analysis tools, command line options not used by ROSE are passed to the backend compiler. In this example the -c
option is not used by ROSE and is passed through to the backend compiler. Options that start with -rose:
are options for ROSE or the tool you are using, though some tools use options that do not begin with -rose:
. The -rose:merge_decl_assign
is a tool specific option that will merge declarations with their first assignment which results in the following code.
#define REG register
void AccumulateForce(int *idxBound,int *idxList,int len,double *tmp,double *force)
{
//These declarations can be moved inside the loop
for (register int ii = 0; ii < len; ++ii) {
int count = idxBound[ii + 1] - idxBound[ii];
int *list = &idxList[idxBound[ii]];
double sum = 0.0;
for (register int jj = 0; jj < count; ++jj) {
int idx = list[jj];
sum += tmp[idx];
}
force[ii] += sum;
}
return ;
}
Like anaylis tools, transformation tools can be integrated into a build system by replacing the compiler with a ROSE tool. By setting CXX or CC to the ROSE tool and adding any tool options, your build system should then run the tool on all files in the system. The transformed code files will be saved to the directory where the command was run from.
export CXX="moveDeclarationToInnermostScope -rose:unparse_tokens -rose:merge_decl_assign"
A few things to notice about the transformed code formatting:
- Comments and names are preserved
- Some differences in formatting, such as the white space betwee nthe semicoon and the rest of the line was removed.
- The macro has been resolved in the transformed code.
Some of the formatting can be preserved by using the -rose:unparse_tokens
option which makes ROSE take extra care to preserve source code formatting. The command line and results of using -rose:unparse_tokens
are below.
moveDeclarationToInnermostScope -rose:unparse_tokens -rose:merge_decl_assign -c Test.cc
#define REG register
void AccumulateForce(int *idxBound, int *idxList, int len, double *tmp, double *force){
//These declarations can be moved inside the loop
for (register int ii = 0; ii<len; ++ii) {
int count = idxBound[ii + 1] - idxBound[ii];
int *list = &idxList[idxBound[ii]];
double sum = 0.0;
for (register int jj = 0; jj<count; ++jj) {
int idx = list[jj];
sum += tmp[idx] ;
}
force[ii] += sum ;
}
return ;
}