/* * Copyright (C) 2016-2017 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ "use strict"; class Driver { constructor(statusCell, triggerCell, triggerLink, magicCell, summaryCell, key) { this._benchmarks = new Map(); this._statusCell = statusCell; this._triggerCell = triggerCell; this._triggerLink = triggerLink; this._magicCell = magicCell; this._summary = new Stats(summaryCell, "summary"); this._key = key; this._values = []; this._names = []; if (isInBrowser) window[key] = this; } addBenchmark(benchmark) { this._benchmarks.set(benchmark, new Results(benchmark)); } readyTrigger() { if (isInBrowser) { this._triggerCell.addEventListener('click', this._triggerLink); this._triggerCell.classList.add('ready'); } } disableTrigger() { if (isInBrowser) { this._triggerCell.removeEventListener('click', this._triggerLink); this._triggerCell.classList.remove('ready'); } } start(numIterations) { this.disableTrigger(); this._updateIterations(); this._summary.reset(); for (let [benchmark, results] of this._benchmarks) results.reset(); this._isRunning = true; this._startIterations = this._numIterations = numIterations; this._iterator = null; this._iterate(); } reportResult(...args) { this._benchmarks.get(this._benchmark).reportResult(...args); this._recomputeSummary(); this._iterate(); } reportError(...args) { if (isInBrowser) console.log("Error encountered: ", ...args); this._benchmarks.get(this._benchmark).reportError(...args); if (isInBrowser) { this._statusCell.innerHTML = "Test failure \u2014 error in console"; this._statusCell.classList.add("failed"); } else print("Test failure"); } _recomputeSummary() { class Geomean { constructor() { this._count = 0; this._sum = 0; } add(value) { this._count++; this._sum += Math.log(value); } get result() { return Math.exp(this._sum * (1 / this._count)); } } let statses = []; for (let [benchmark, results] of this._benchmarks) { for (let subResult of Results.subResults) { statses.push(results[subResult]); let val = results[subResult].valueForIteration(results[subResult].numIterations - 1); if (val > 0 && benchmark.name == this._benchmark.name) { this._values.push(val); this._names.push(benchmark.name + "_" + subResult); } } } let numIterations = Math.min(...statses.map(stats => stats.numIterations)); let data = new Array(numIterations); for (let i = 0; i < data.length; ++i) data[i] = new Geomean(); for (let stats of statses) { for (let i = 0; i < data.length; ++i) data[i].add(stats.valueForIteration(i)); } let geomeans = data.map(geomean => geomean.result); if (geomeans.length == this._startIterations) { for (let iter = 0; iter < geomeans.length; iter++) { this._values.push(geomeans[iter]); this._names.push("geomean"); } } this._summary.reset(...geomeans); } _iterate() { this._benchmark = this._iterator ? this._iterator.next().value : null; if (!this._benchmark) { if (!this._numIterations) { if (isInBrowser) { this._statusCell.innerHTML = "Restart"; this.readyTrigger(); if (typeof tpRecordTime !== "undefined") tpRecordTime(this._values.join(','), 0, this._names.join(',')); this.sendResultsToRaptor(); } else print("Success! Benchmark is now finished."); return; } this._numIterations--; this._updateIterations(); this._iterator = this._benchmarks.keys(); this._benchmark = this._iterator.next().value; } this._benchmarks.get(this._benchmark).reportRunning(); let benchmark = this._benchmark; if (isInBrowser) { window.setTimeout(() => { if (!this._isRunning) return; this._magicCell.contentDocument.body.textContent = ""; this._magicCell.contentDocument.body.innerHTML = "