Skip to content

Commit

Permalink
Added support for perf testing
Browse files Browse the repository at this point in the history
- Fixed reverse gate shaders stopping at 15 instead of 16 span
  • Loading branch information
Strilanc committed Oct 16, 2016
1 parent f14aedc commit bfeb0cf
Show file tree
Hide file tree
Showing 8 changed files with 296 additions and 6 deletions.
48 changes: 44 additions & 4 deletions GruntFile.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,23 +33,41 @@ module.exports = function(grunt) {
src: ['**/*.js'],
dest: 'out/tmp/traceur/test/'
}]
},
'translate-test-perf': {
options: {
experimental: true,
moduleNaming: {
stripPrefix: 'out/tmp/traceur'
}
},
files: [{
expand: true,
cwd: 'test_perf/',
src: ['**/*.js'],
dest: 'out/tmp/traceur/test_perf/'
}]
}
},
karma: {
unit: {
configFile: 'karma.conf.js'
configFile: 'karma.test.conf.js'
},
'unit-chrome': {
configFile: 'karma.conf.js',
configFile: 'karma.test.conf.js',
browsers: ['Chrome']
},
'unit-firefox': {
configFile: 'karma.conf.js',
configFile: 'karma.test.conf.js',
browsers: ['Firefox']
},
'unit-travis': {
configFile: 'karma.conf.js',
configFile: 'karma.test.conf.js',
browsers: ['Firefox']
},
'perf-chrome': {
configFile: 'karma.test_perf.conf.js',
browsers: ['Chrome']
}
},
concat: {
Expand All @@ -76,6 +94,19 @@ module.exports = function(grunt) {
'out/tmp/traceur/bootstrap_post_test/**/*.js'
],
dest: 'out/test.js'
},
'concat-traceur-test-perf': {
options: {
separator: ';'
},
src: [
'out/tmp/traceur/bootstrap_pre_src/**/*.js',
'out/tmp/traceur/bootstrap_pre_test/**/*.js',
'out/tmp/traceur/src/**/*.js',
'out/tmp/traceur/test_perf/**/*.js',
'out/tmp/traceur/bootstrap_post_test/**/*.js'
],
dest: 'out/test_perf.js'
}
},
uglify: {
Expand Down Expand Up @@ -165,7 +196,16 @@ module.exports = function(grunt) {
'concat:concat-traceur-test',
'clean:clean-tmp'
]);
grunt.registerTask('build-test-perf', [
'clean:clean-tmp',
'traceur:translate-src',
'traceur:translate-test-perf',
'bootstrap-get-packages:test_perf/**/*.perf.js:out/tmp/traceur/bootstrap_post_test/run_tests.js',
'concat:concat-traceur-test-perf',
'clean:clean-tmp'
]);

grunt.registerTask('test-perf-chrome', ['build-test-perf', 'karma:perf-chrome']);
grunt.registerTask('test-chrome', ['build-test', 'karma:unit-chrome']);
grunt.registerTask('test-firefox', ['build-test', 'karma:unit-firefox']);
grunt.registerTask('test-travis', ['build-test', 'karma:unit-travis']);
Expand Down
File renamed without changes.
17 changes: 17 additions & 0 deletions karma.test_perf.conf.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
module.exports = function(config) {
config.set({
basePath: '',
frameworks: [],
files: ['out/test_perf.js'],
exclude: [],
preprocessors: {},
reporters: ['dots'],
port: 19876,
colors: true,
browserNoActivityTimeout: 30000,
logLevel: config.LOG_INFO,
autoWatch: false,
browsers: ['Chrome', 'Firefox'],
singleRun: true
});
};
2 changes: 1 addition & 1 deletion src/circuit/Gate.js
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ class Gate {
* @param {!string} blurb
* @returns {!Gate}
*/
static fromKnownMatrix(symbol, matrix, name, blurb) {
static fromKnownMatrix(symbol, matrix, name='', blurb='') {
if (!(matrix instanceof Matrix)) {
throw new DetailedError("Bad matrix.", {symbol, matrix, name, blurb});
}
Expand Down
2 changes: 1 addition & 1 deletion src/gates/ReverseBitsGate.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ let _generateReverseShaderForSize = span => span < 2 ? undefined : ketShaderPerm
`,
span);

let reverseShaders = Seq.range(Config.MAX_WIRE_COUNT).map(_generateReverseShaderForSize).toArray();
let reverseShaders = Seq.range(Config.MAX_WIRE_COUNT + 1).map(_generateReverseShaderForSize).toArray();

/**
* @param {!int} span
Expand Down
43 changes: 43 additions & 0 deletions test_perf/KarmaTestRunner.perf.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import {getKnownPerfTests} from "test_perf/TestPerfUtil.js";

let execIntoPromise = method => {
try {
return Promise.resolve(method());
} catch (ex) {
return Promise.reject(ex);
}
};

let promiseRunPerfTest = ({name, method}) => {
let result = {
description: name,
suite: ['(Perf Tests)'],
success: false,
log: [],
time: undefined
};

let t0 = performance.now();
return execIntoPromise(method).then(
passed => {
result.success = passed;
},
ex => {
result.log.push(String(ex));
if (ex.details !== undefined) {
result.log.push(ex.details);
}
if (ex.stack !== undefined) {
result.log.push(ex.stack);
}
}).then(() => {
result.time = performance.now() - t0;
__karma__.result(result);
});
};

__karma__.start = () => {
let known = getKnownPerfTests();
__karma__.info({ total: known.length });
Promise.all(known.map(promiseRunPerfTest)).then(() => __karma__.complete());
};
75 changes: 75 additions & 0 deletions test_perf/TestPerfUtil.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
function nanos(nanoseconds) {
return {
duration_nanos: nanoseconds,
description: nanoseconds + " ns"
};
}

function micros(microseconds) {
return {
duration_nanos: microseconds * 1.0e3,
description: microseconds + " us"
};
}

function millis(milliseconds) {
return {
duration_nanos: milliseconds * 1.0e6,
description: milliseconds + " ms"
};
}

let _knownPerfTests = [];
function getKnownPerfTests() {
return _knownPerfTests;
}

/**
* @param {!string} name
* @param {!{duration_nanos: !int, description: !string}} targetDuration
* @param {!function(*):*} method
* @param {undefined|*=undefined} arg
*/
function perfGoal(name, targetDuration, method, arg=undefined) {
//noinspection JSUnusedGlobalSymbols
_knownPerfTests.push({name, method: () => {
let dt = _measureDuration(method, arg, targetDuration.duration_nanos);
let p = dt.duration_nanos / targetDuration.duration_nanos;
let logger = (p > 1 ? console.warn : console.log);
logger(`${_proportionDesc(p)} of target (${_pad(targetDuration.description, 6)}) for ${name}`);
return dt.duration_nanos <= targetDuration.duration_nanos
}});
}

function _pad(obj, length) {
let v = `${obj}`;
return ' '.repeat(Math.max(0, length - v.length)) + v;
}

function _proportionDesc(proportion) {
return `[${_proportionBar(proportion)}] ${_pad(Math.round(proportion*100), 2)}%`;
}

function _proportionBar(proportion, length=20) {
if (proportion > 1) {
return '!'.repeat(length);
}
let n = Math.round(proportion * length);
return '#'.repeat(n) + ' '.repeat(length - n);
}

function _measureDuration(method, arg, expected_nanos_hint) {
let ms = 1.0e6;
let repeats = expected_nanos_hint < 30 * ms ? 50 : 10;
// Dry run to get any one-time initialization done.
method(arg);

let t0 = window.performance.now();
for (let i = 0; i < repeats; i++) {
method(arg);
}
let t1 = window.performance.now();
return {duration_nanos: (t1 - t0) / repeats * ms};
}

export {getKnownPerfTests, perfGoal, nanos, micros, millis}
115 changes: 115 additions & 0 deletions test_perf/circuit.perf.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
import {perfGoal, millis} from "test_perf/TestPerfUtil.js"
import {CircuitDefinition} from "src/circuit/CircuitDefinition.js"
import {CircuitStats} from "src/circuit/CircuitStats.js"
import {Gate} from "src/circuit/Gate.js"
import {Gates} from "src/gates/AllGates.js"
import {Matrix} from "src/math/Matrix.js"

perfGoal(
"2-Qubit QFT gate with manual de-QFT",
millis(15),
circuit => CircuitStats.fromCircuitAtTime(circuit, 0),
CircuitDefinition.fromTextDiagram(
new Map([
['•', Gates.Controls.Control],
['H', Gates.HalfTurns.H],
['1', Gates.QuarterTurns.SqrtZForward],
['-', undefined],
['/', undefined],
['Q', Gates.FourierTransformGates.InverseFourierTransformFamily.ofSize(2)]
]),
`-Q-H-1---
-/---•-H-`));

perfGoal(
"4-Qubit QFT gate with manual de-QFT",
millis(15),
circuit => CircuitStats.fromCircuitAtTime(circuit, 0),
CircuitDefinition.fromTextDiagram(
new Map([
['•', Gates.Controls.Control],
['H', Gates.HalfTurns.H],
['1', Gates.QuarterTurns.SqrtZForward],
['2', Gates.OtherZ.Z4],
['3', Gates.OtherZ.Z8],
['-', undefined],
['/', undefined],
['Q', Gates.FourierTransformGates.InverseFourierTransformFamily.ofSize(4)]
]),
`-Q-H-1---2---3---
-/---•-H-1---2---
-/-------•-H-1---
-/-----------•-H-`));

perfGoal(
"8-Qubit QFT gate with manual de-QFT",
millis(25),
circuit => CircuitStats.fromCircuitAtTime(circuit, 0),
CircuitDefinition.fromTextDiagram(
new Map([
['•', Gates.Controls.Control],
['H', Gates.HalfTurns.H],
['1', Gates.QuarterTurns.SqrtZForward],
['2', Gates.OtherZ.Z4],
['3', Gates.OtherZ.Z8],
['4', Gates.OtherZ.Z16],
['5', Gates.OtherZ.Z32],
['6', Gates.OtherZ.Z64],
['7', Gates.OtherZ.Z128],
['-', undefined],
['/', undefined],
['Q', Gates.FourierTransformGates.InverseFourierTransformFamily.ofSize(8)]
]),
`-Q-H-1---2---3---4---5---6---7---
-/---•-H-1---2---3---4---5---6---
-/-------•-H-1---2---3---4---5---
-/-----------•-H-1---2---3---4---
-/---------------•-H-1---2---3---
-/-------------------•-H-1---2---
-/-----------------------•-H-1---
-/---------------------------•-H-`));


perfGoal(
"16-Qubit QFT gate with manual de-QFT",
millis(200),
circuit => CircuitStats.fromCircuitAtTime(circuit, 0),
CircuitDefinition.fromTextDiagram(
new Map([
['•', Gates.Controls.Control],
['H', Gates.HalfTurns.H],
['1', Gates.QuarterTurns.SqrtZForward],
['2', Gates.OtherZ.Z4],
['3', Gates.OtherZ.Z8],
['4', Gates.OtherZ.Z16],
['5', Gates.OtherZ.Z32],
['6', Gates.OtherZ.Z64],
['7', Gates.OtherZ.Z128],
['8', Gate.fromKnownMatrix("8", Matrix.fromPauliRotation(0, 0, 1/(1<<9)))],
['9', Gate.fromKnownMatrix("9", Matrix.fromPauliRotation(0, 0, 1/(1<<10)))],
['A', Gate.fromKnownMatrix("A", Matrix.fromPauliRotation(0, 0, 1/(1<<11)))],
['B', Gate.fromKnownMatrix("B", Matrix.fromPauliRotation(0, 0, 1/(1<<12)))],
['C', Gate.fromKnownMatrix("C", Matrix.fromPauliRotation(0, 0, 1/(1<<13)))],
['D', Gate.fromKnownMatrix("D", Matrix.fromPauliRotation(0, 0, 1/(1<<14)))],
['E', Gate.fromKnownMatrix("E", Matrix.fromPauliRotation(0, 0, 1/(1<<15)))],
['F', Gate.fromKnownMatrix("F", Matrix.fromPauliRotation(0, 0, 1/(1<<16)))],
['-', undefined],
['/', undefined],
['Q', Gates.FourierTransformGates.InverseFourierTransformFamily.ofSize(16)]
]),
`-Q-H-1---2---3---4---5---6---7---8---9---A---B---C---D---E---F---
-/---•-H-1---2---3---4---5---6---7---8---9---A---B---C---D---E---
-/-------•-H-1---2---3---4---5---6---7---8---9---A---B---C---D---
-/-----------•-H-1---2---3---4---5---6---7---8---9---A---B---C---
-/---------------•-H-1---2---3---4---5---6---7---8---9---A---B---
-/-------------------•-H-1---2---3---4---5---6---7---8---9---A---
-/-----------------------•-H-1---2---3---4---5---6---7---8---9---
-/---------------------------•-H-1---2---3---4---5---6---7---8---
-/-------------------------------•-H-1---2---3---4---5---6---7---
-/-----------------------------------•-H-1---2---3---4---5---6---
-/---------------------------------------•-H-1---2---3---4---5---
-/-------------------------------------------•-H-1---2---3---4---
-/-----------------------------------------------•-H-1---2---3---
-/---------------------------------------------------•-H-1---2---
-/-------------------------------------------------------•-H-1---
-/-----------------------------------------------------------•-H-`));

0 comments on commit bfeb0cf

Please sign in to comment.