UNPKG

@eagleoutice/flowr

Version:

Static Dataflow Analyzer and Program Slicer for the R Programming Language

101 lines 5.7 kB
"use strict"; 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 the path contains one if (directory !== '') { fs_1.default.mkdirSync(directory, { recursive: true }); } const config = config_1.FlowrConfig.fromFile(); // 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, config, 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 = Number.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'], seed: options.seed }); 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`); } if (options['cfg'] || options['dataframe-shape-inference']) { slicer.extractCFG(); } if (options['cg']) { slicer.extractCG(); } if (options['dataframe-shape-inference']) { console.log(`${prefix} Performing shape inference for data frames`); slicer.inferDataFrameShapes(); console.log(`${prefix} Completed data frame shape inference`); } 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