@eagleoutice/flowr
Version:
Static Dataflow Analyzer and Program Slicer for the R Programming Language
96 lines • 5.52 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const fs_1 = __importDefault(require("fs"));
const log_1 = require("../util/log");
const assert_1 = require("../util/assert");
const json_1 = require("../util/json");
const script_1 = require("./common/script");
const slicer_1 = require("../benchmark/slicer");
const all_variables_1 = require("../slicing/criterion/filters/all-variables");
const path_1 = __importDefault(require("path"));
const config_1 = require("../config");
const options = (0, script_1.processCommandLineArgs)('benchmark-helper', [], {
subtitle: 'Will slice for all possible variables, signal by exit code if slicing was successful, and can be run standalone',
examples: [
'{italic example-file.R} --output {italic output.json}',
'{bold --help}'
]
});
if (options.verbose) {
log_1.log.error('running with *verbose* setting - do not use for final benchmark', options);
}
const numberRegex = /^\d+$/;
(0, assert_1.guard)(options.slice === 'all' || options.slice === 'no' || numberRegex.test(options.slice), 'slice must be either all, no, or a number');
(0, assert_1.guard)(options['sampling-strategy'] === 'random' || options['sampling-strategy'] === 'equidistant', 'sample-strategy must be either random or equidistant');
async function benchmark() {
// we do not use the limit argument to be able to pick the limit randomly
(0, assert_1.guard)(options.input !== undefined, 'No input file given');
(0, assert_1.guard)(options.output !== undefined, 'No output file given');
(0, assert_1.guard)((options['file-id'] === undefined) === (options['run-num'] === undefined), 'When giving a file-id or run-num, both have to be given');
// prefix for printing to console, includes file id and run number if present
const prefix = `[${options.input}${options['file-id'] !== undefined ? ` (file ${options['file-id']}, run ${options['run-num']})` : ''}]`;
console.log(`${prefix} Appending output to ${options.output}`);
const directory = path_1.default.parse(options.output).dir;
// ensure the directory exists if path contains one
if (directory !== '') {
fs_1.default.mkdirSync(directory, { recursive: true });
}
// Enable pointer analysis if requested, otherwise disable it
if (options['enable-pointer-tracking']) {
(0, config_1.amendConfig)({ solver: { ...(0, config_1.getConfig)().solver, pointerTracking: true, } });
}
else {
(0, config_1.amendConfig)({ solver: { ...(0, config_1.getConfig)().solver, pointerTracking: false, } });
}
// ensure the file exists
const fileStat = fs_1.default.statSync(options.input);
(0, assert_1.guard)(fileStat.isFile(), `File ${options.input} does not exist or is no file`);
const request = { request: 'file', content: options.input };
const maxSlices = options['max-slices'] ?? -1;
const slicer = new slicer_1.BenchmarkSlicer(options.parser);
try {
await slicer.init(request, undefined, options.threshold);
// ${escape}1F${escape}1G${escape}2K for line reset
if (options.slice === 'all') {
const count = await slicer.sliceForAll(all_variables_1.DefaultAllVariablesFilter, (i, total, arr) => console.log(`${prefix} Slicing ${i + 1}/${total} [${JSON.stringify(arr[i])}]`), { maxSliceCount: maxSlices });
console.log(`${prefix} Completed Slicing`);
(0, assert_1.guard)(count >= 0, `Number of slices exceeded limit of ${maxSlices} with ${-count} slices, skipping in count`);
(0, assert_1.guard)(count > 0, `No possible slices found for ${options.input}, skipping in count`);
}
else if (options.slice === 'no') {
console.log(`${prefix} Skipping Slicing due to --slice=${options.slice}`);
}
else {
const limit = parseInt(options.slice);
console.log(`${prefix} Slicing up to ${limit} possible slices`);
const count = await slicer.sliceForAll(all_variables_1.DefaultAllVariablesFilter, (i, total, arr) => console.log(`${prefix} Slicing ${i + 1}/${total} [${JSON.stringify(arr[i])}]`), { sampleCount: limit, maxSliceCount: maxSlices, sampleStrategy: options['sampling-strategy'] });
console.log(`${prefix} Completed Slicing`);
(0, assert_1.guard)(count >= 0, `Number of slices exceeded limit of ${maxSlices} with ${-count} slices, skipping in count`);
(0, assert_1.guard)(count > 0, `No possible slices found for ${options.input}, skipping in count`);
}
const { stats } = slicer.finish();
const output = {
filename: options.input,
'file-id': options['file-id'],
'run-num': options['run-num'],
stats
};
// append line by line
console.log(`Appending benchmark of ${options.input} to ${options.output}`);
fs_1.default.appendFileSync(options.output, `${JSON.stringify(output, json_1.jsonReplacer)}\n`);
}
catch (e) {
if (e instanceof Error) {
if (!e.message.includes('unable to parse R')) {
console.log(`${prefix} Non R-Side error : ${e.name} ${e.message} ${e.stack}`);
}
}
slicer.ensureSessionClosed(); // ensure finish
throw e;
}
}
void benchmark();
//# sourceMappingURL=benchmark-helper-app.js.map