Usage¶
Modifying the code¶
This section details how to use PROMISE. First you need to modify your source code to tell PROMISE which variables you want to be considered, and which output(s) should be considered for the final accuracy. And then, you can run PROMISE and get some results.
Defining the types to be considered¶
To use PROMISE on your C/C++ code, you first need to instrument your code and change the type of the variables you want to change in quad/double/single/half. This is done by introducing a __PROMISE__
type, and you need to change manually [1] the type of these variables.
So
double a,b;
becomes
__PROMISE__ a,b;
All the variables defined with the __PROMISE__
type will be examined, and different types (quad, double, float, half) will be tried. Note that a
and b
are defined with the __PROMISE__
type but their types are not linked, and will not be necessarily the same.
In order to link types, another dedicated PROMISE type can be used, in the form __PR_xxxx__
where xxxx
is user defined. For example, to define that a variable must have the same type as the return type of a function, we can write
__PR_ret__ foo(int bar, double x) {
__PR_ret__ y;
y = x*bar;
return y;
}
If we use __PROMISE__
for the return type of foo
and for y
, PROMISE may try two different types. So, in order to have two variables a
and b
with the same type chosen by PROMISE, we must define
__PR_ab__ a,b;
Specifying the output(s)¶
Two functions [2] are used to tell PROMISE which variables to check:
PROMISE_CHECK_VAR
to check a variablePROMISE_CHECK_ARRAY
to check an array
So, if you want PROMISE to check the accuracy of the variable res
at the end of a given computation, you need to add
PROMISE_CHECK_VAR(res);
after the computation.
If res
is an array, then
PROMISE_CHECK_ARRAY(res, size);
should be used (where size
is an integer with the array size). Then all the values of the array are checked to determine if they satisfy the accuracy requirement.
PROMISE_CHECK_VAR
can be called several times (with the same variable or not), and in that case, all the occurrences are checked against the requirements.
Run PROMISE¶
The Promise.yml
file¶
Once your code is adapted to PROMISE, it’s time to run PROMISE. For that, there is a script called runPromise
that has been created (usually in /usr/local/bin/
) when installing PROMISE.
To run, PROMISE needs to know:
where is your source code
how to compile it
how many digits you need for the specified output(s)
All these informations (and other options) are given in a specific yml
config file, named promise.yml
by default.
It should contains the following informations:
|
a yml list of commands to compile the source code. The compilation should include the CADNA library, so options such as |
|
executable name produced by the compilation process |
|
comma-separated list of source files (files considered and parsed by PROMISE) |
|
required (general) number of correct digits |
The following informations are optional:
|
dedicated number of digits per variable (should be a yml dictionary: for each variable name, an integer is given). For the variables not defined here, the (general) number of digits given in |
|
name of the log file (no log file if this is not defined) |
|
verbosity level (integer between 0 and 4). 0 means minimum messages, 1 (default level) for some info messages, 2 for debug messages, 3 to display the command lines used and 4 to get the promise-dedicated outputs of the runs |
|
verbosity level for the log file (the integer values already mentioned) |
|
name of the output repository ( |
A minimum promise.yml
file could be (for a simple project based on foo.cc
and bar.cc
and 8 expected digits):
compile:
- g++ -c foo.cc -I$CADNA_PATH/include
- g++ -c bar.cc -I$CADNA_PATH/include
- g++ foo.o bar.o -o mytest.out -lcadnaC -L$CADNA_PATH/lib -I$CADNA_PATH/include
run: mytest.out
files: foo.cc, bar.cc
nbDigits: 8
Using all the options, we can have something like (we expect 4 digits for the variable x
, 2 for foo
and 8 for the other variables):
compile:
- g++ -c foo.cc -I$CADNA_PATH/include
- g++ -c bar.cc -I$CADNA_PATH/include
- g++ foo.o bar.o -o mytest.out -lcadnaC -L$CADNA_PATH/lib -I$CADNA_PATH/include
run: mytest.out
files: foo.cc, bar.cc
nbDigits: 8
nbDigitsPerVariable:
x: 4
foo: 2
log: mylog.txt
verbosity: 1
verbosityLog: 4
output: finalResult/
Command line usage¶
In addition to the parameters put in the promise.yml
, we need to tell PROMISE which floating-point tuning it should do.
The command runPromise
is used to run PROMISE, followed with one of the three [3] possibilities:
hsd
for Half/Single/Double mixed-precisionhs
for Half/Single mixed-precisionsd
for Single/Double mixed-precision
So the command:
$ runPromise sd
simply runs PROMISE for Single/Double mixed-precision using the parameters from the promise.yml
file in the current directory.
The option --conf CONF_FILE
can be used to indicate PROMISE that the file CONF_FILE
should be used instead of promise.yml
(used to specify the path of promise.yml
for example).
The option --debug
can also be used for developing PROMISE (it displays execution traces when an error arises and puts the intermediate results in the debug/
folder.
The option --pause
is used to force a pause between the different steps of the Delta Debug algorithm (sometimes used for debugging).
Moreover, all the previous options can also be specified in the command line, by prefixing them with --
(if an option is specified in both, the command line value prevails). They are gathered in the usage documentation (obtained with runPromise --help
):
Promise v2
Usage:
runPromise -h | --help
runPromise (hsd|hs|sd) [options]
Options:
-h --help Show this screen.
--conf CONF_FILE get the configuration file [default: promise.yml]
--output OUTPUT set the path of the output (where the result files are put)
--verbosity VERBOSITY set the verbosity (betwen 0 display the minimum and 4 for very low level debug) [default: 1]
--log LOGFILE set the log file (no log file if this is not defined)
--verbosityLog VERBOSITY set the verbosity of the log file
--debug put intermediate files into `debug/` and display the execution trace when an error comes (only use during promise development)
--run RUN file to be run
--compile COMMAND command to compile the code
--files FILES list of files to be examined by PROMISE (by default, all the .cc files)
--nbDigits DIGITS general required number of correct digits
--path PATH set the path of the project (by default, the current path)
--pause do pause between steps
hsd Half/Single/Double mixed-precision
hs Half/Single mixed-precision
sd Single/Double mixed-precision
Usually, the common options used for a project are put in the promise.yml
file (like the compilation commands, the files, etc.), whereas the options frequently changed (for various attempts) are put in the command line (like the number of digits or the verbosity level). A typical runPromise
command can be:
runPromise hsd --nbDigits=5 --verbosity=2
Warning
The parsing done to recognize the type of the variables (__PROMISE__
and __PR_xxx__
-like) is not robust to all the codes. For example, array declarations and initializations may not work.