Last active
October 23, 2023 11:04
-
-
Save miyaokamarina/2da5f784fde9c9f8924f60b4475f14f6 to your computer and use it in GitHub Desktop.
Running TestU01 BigCrush in parallel
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// The worker binary. | |
// Compile as | |
// gcc -Wall -O3 -o ./OUT_DIR/tu01 ./tu01.c | |
// -Iinclude -Llib -ltestu01 -lprobdist -lmylib -lm | |
#include <TestU01.h> | |
// Should provide: | |
// • void reset(); -- Init/reset the state. | |
// • uint32_t fwd(); -- Generate random u32, normal bit order. | |
// • uint32_t rev(); -- Generate random u32, reverse bit order. | |
#include "my-prng.h" | |
int main(int argc, char **argv) { | |
swrite_Basic = false; | |
bool reverse = false; | |
uint32_t test = 0; | |
uint32_t runs = 0; | |
int32_t rep[107] = {}; | |
while (1) { | |
argc--; | |
argv++; | |
if (argc == 0) | |
break; | |
switch (argv[0][1]) { | |
case 'r': // Reverse bits | |
reverse = true; | |
break; | |
case 't': // Test # | |
argc--; | |
argv++; | |
sscanf(argv[0], "%d", &test); | |
break; | |
case 'n': // Runs of the test | |
argc--; | |
argv++; | |
sscanf(argv[0], "%d", &runs); | |
break; | |
case 'v': // Verbose | |
swrite_Basic = true; | |
break; | |
} | |
} | |
rep[test] = runs; | |
reset(); // Init/reset the state of RNG | |
unif01_Gen *gen = reverse | |
? unif01_CreateExternGenBits("My PRNG [Reverse]", rev) | |
: unif01_CreateExternGenBits("My PRNG [Forward]", fwd); | |
bbattery_RepeatBigCrush(gen, rep); | |
unif01_DeleteExternGenBits(gen); | |
return 0; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// @ts-check | |
// The scheduler srcipt. | |
import { spawn } from 'node:child_process'; | |
// Compiled binary name: | |
const BIN = './tmp/tu01'; | |
// Repeat each test N times. | |
const N = 3; | |
// Run tests ## [MIN, MAX] (inclusive). | |
// To run single test, set MIN = MAX. | |
const MIN_TEST = 1; | |
const MAX_TEST = 106; | |
const main = () => { | |
// Number of processes to spawn. | |
// Set to the number of CPUs/threads or whatever you want. | |
let active = 8; | |
/** @type {Task[]} */ | |
let queue = []; | |
// • Fill the queue. | |
for (let test = MIN_TEST; test <= MAX_TEST; test++) { | |
queue.push({ test, reverse: true }); | |
queue.push({ test, reverse: false }); | |
} | |
// • Adjust the number of workers. | |
active = Math.min(active, queue.length); | |
// • Pull a task. | |
// • Run it. | |
// • Handle its finish. | |
// • Also handle the queue finish. | |
const enqueue = () => { | |
let task = queue.shift(); | |
// No tasks left: | |
if (!task) active--; | |
// The last task is finished: | |
if (active === 0) { | |
for (let i = MIN_TEST; i <= MAX_TEST; i++) { | |
let p = pad3(i); | |
report(`${p}-0`); | |
report(`${p}-1`); | |
} | |
return; | |
} | |
if (!task) return; | |
let a = performance.now(); | |
console.error( | |
'[RUNNING] Test#%o %o [%s]', | |
task.test, | |
BIG_CRUSH_NAMES[task.test], | |
task.reverse ? 'Reverse' : 'Forward', | |
); | |
run(task).then(({ task, stdout, stderr, status }) => { | |
let b = performance.now(); | |
let time = b - a; | |
let pass = stdout.endsWith('All tests were passed'); | |
console.error( | |
'%s Test#%o %o [%s] in %os', | |
pass ? '[OK] ' : '[FAILED] ', | |
task.test, | |
BIG_CRUSH_NAMES[task.test], | |
task.reverse ? 'Reverse' : 'Forward', | |
Math.round(time / 1000), | |
); | |
reports.set(`${pad3(task.test)}-${Number(task.reverse)}`, { | |
test: task.test, | |
reverse: task.reverse, | |
stdout, | |
stderr, | |
status, | |
time, | |
pass, | |
}); | |
enqueue(); | |
}); | |
}; | |
// • Spawn workers. | |
for (let i = 0; i < active; i++) { | |
enqueue(); | |
} | |
}; | |
/** | |
* @typedef {object} Report | |
* @prop {number} test | |
* @prop {boolean} reverse | |
* @prop {string} stdout | |
* @prop {string} stderr | |
* @prop {number} status | |
* @prop {number} time | |
* @prop {boolean} pass | |
* | |
* @typedef {object} Task | |
* @prop {number} test | |
* @prop {boolean} reverse | |
* | |
* @typedef {object} Output | |
* @prop {Task} task | |
* @prop {string} stdout | |
* @prop {string} stderr | |
* @prop {number} status | |
*/ | |
/** @type {Map<string, Report>} */ | |
let reports = new Map(); | |
/** @param {Task} task */ | |
const run = task => { | |
return /** @type {Promise<Output>} */ ( | |
new Promise((resolve, reject) => { | |
/** @type {string[]} */ | |
let args = ['-t', String(task.test), '-n', String(N)]; | |
if (task.reverse) args.push('-r'); | |
let proc = spawn(BIN, args); | |
let stdout = []; | |
let stderr = []; | |
let settled = false; | |
proc.stdout.on('data', chunk => stdout.push(chunk)); | |
proc.stderr.on('data', chunk => stderr.push(chunk)); | |
proc.on('close', status => { | |
if (settled) return; | |
settled = true; | |
resolve({ | |
task, | |
stdout: trim(stdout.join('')), | |
stderr: trim(stderr.join('')), | |
status: status ?? 0, | |
}); | |
}); | |
proc.on('error', error => { | |
if (settled) return; | |
settled = true; | |
reject(error); | |
}); | |
}) | |
); | |
}; | |
/** @param {string} k */ | |
const report = k => { | |
let report = reports.get(k); | |
if (!report) return; | |
let { test, reverse, stdout, stderr, status, time, pass } = report; | |
console.log([test, BIG_CRUSH_NAMES[test], reverse, pass, time, status].join(',')); | |
console.log('# stdout'); | |
console.log(indent(stdout)); | |
console.log('# stderr'); | |
console.log(indent(stderr)); | |
}; | |
/** @param {number} n */ | |
const pad3 = n => n.toString().padStart(3, '0'); | |
/** @param {string} s */ | |
const trim = s => { | |
return s | |
.trim() | |
.split('\n') | |
.map(x => x.trimEnd()) | |
.join('\n') | |
.replace(/\n\n+/g, '\n'); | |
}; | |
/** @param {string} s */ | |
const indent = s => { | |
return trim( | |
s | |
.split('\n') | |
.map(x => '# -- ' + x) | |
.join('\n'), | |
); | |
}; | |
const BIG_CRUSH_NAMES = [ | |
null, | |
'smarsa_SerialOver with N = 1, n = 10⁹, r = 0, d = 2⁸, t = 3', | |
'smarsa_SerialOver with N = 1, n = 10⁹, r = 22, d = 2⁸, t = 3', | |
'smarsa_CollisionOver with N = 30, n = 2×10⁷, r = 0, d = 2²¹, t = 2', | |
'smarsa_CollisionOver with N = 30, n = 2×10⁷, r = 9, d = 2²¹, t = 2', | |
'smarsa_CollisionOver with N = 30, n = 2×10⁷, r = 0, d = 2¹⁴, t = 3', | |
'smarsa_CollisionOver with N = 30, n = 2×10⁷, r = 16, d = 2¹⁴, t = 3', | |
'smarsa_CollisionOver with N = 30, n = 2×10⁷, r = 0, d = 2⁶, t = 7', | |
'smarsa_CollisionOver with N = 30, n = 2×10⁷, r = 24, d = 2⁶, t = 7', | |
'smarsa_CollisionOver with N = 30, n = 2×10⁷, r = 0, d = 2³, t = 14', | |
'smarsa_CollisionOver with N = 30, n = 2×10⁷, r = 27, d = 2³, t = 14', | |
'smarsa_CollisionOver with N = 30, n = 2×10⁷, r = 0, d = 2², t = 21', | |
'smarsa_CollisionOver with N = 30, n = 2×10⁷, r = 28, d = 2², t = 21', | |
'smarsa_BirthdaySpacings with N = 100, n = 1×10⁷, r = 0, d = 2³¹, t = 2, p = 1', | |
'smarsa_BirthdaySpacings with N = 20, n = 2×10⁷, r = 0, d = 2²¹, t = 3, p = 1', | |
'smarsa_BirthdaySpacings with N = 20, n = 3×10⁷, r = 14, d = 2¹⁶, t = 4, p = 1', | |
'smarsa_BirthdaySpacings with N = 20, n = 2×10⁷, r = 0, d = 2⁹, t = 7, p = 1', | |
'smarsa_BirthdaySpacings with N = 20, n = 2×10⁷, r = 7, d = 2⁹, t = 7, p = 1', | |
'smarsa_BirthdaySpacings with N = 20, n = 3×10⁷, r = 14, d = 2⁸, t = 8, p = 1', | |
'smarsa_BirthdaySpacings with N = 20, n = 3×10⁷, r = 22, d = 2⁸, t = 8, p = 1', | |
'smarsa_BirthdaySpacings with N = 20, n = 3×10⁷, r = 0, d = 2⁴, t = 16, p = 1', | |
'smarsa_BirthdaySpacings with N = 20, n = 3×10⁷, r = 26, d = 2⁴, t = 16, p = 1', | |
'snpair_ClosePairs with N = 30, n = 6×10⁶, r = 0, t = 3, p = 0, m = 30', | |
'snpair_ClosePairs with N = 20, n = 4×10⁶, r = 0, t = 5, p = 0, m = 30', | |
'snpair_ClosePairs with N = 10, n = 3×10⁶, r = 0, t = 9, p = 0, m = 30', | |
'snpair_ClosePairs with N = 5, n = 2×10⁶, r = 0, t = 16, p = 0, m = 30', | |
'sknuth_SimpPoker with N = 1, n = 4×10⁸, r = 0, d = 8, k = 8', | |
'sknuth_SimpPoker with N = 1, n = 4×10⁸, r = 27, d = 8, k = 8', | |
'sknuth_SimpPoker with N = 1, n = 1×10⁸, r = 0, d = 32, k = 32', | |
'sknuth_SimpPoker with N = 1, n = 1×10⁸, r = 25, d = 32, k = 32', | |
'sknuth_CouponCollector with N = 1, n = 2×10⁸, r = 0, d = 8', | |
'sknuth_CouponCollector with N = 1, n = 2×10⁸, r = 10, d = 8', | |
'sknuth_CouponCollector with N = 1, n = 2×10⁸, r = 20, d = 8', | |
'sknuth_CouponCollector with N = 1, n = 2×10⁸, r = 27, d = 8', | |
'sknuth_Gap with N = 1, n = 5×10⁸, r = 0, α = 0, β = 1⁄2⁴', | |
'sknuth_Gap with N = 1, n = 3×10⁸, r = 25, α = 0, β = 1⁄2⁵', | |
'sknuth_Gap with N = 1, n = 1×10⁸, r = 0, α = 0, β = 1⁄2⁷', | |
'sknuth_Gap with N = 1, n = 1×10⁷, r = 20, α = 0, β = 1⁄2¹⁰', | |
'sknuth_Run with N = 5, n = 10⁹, r = 0, ↑ = false', | |
'sknuth_Run with N = 5, n = 10⁹, r = 15, ↑ = true', | |
'sknuth_Permutation with N = 1, n = 1×10⁹, r = 0, t = 3', | |
'sknuth_Permutation with N = 1, n = 1×10⁹, r = 0, t = 5', | |
'sknuth_Permutation with N = 1, n = 5×10⁸, r = 0, t = 7', | |
'sknuth_Permutation with N = 1, n = 5×10⁸, r = 10, t = 10', | |
'sknuth_CollisionPermut with N = 20, n = 2×10⁷, r = 0, t = 14', | |
'sknuth_CollisionPermut with N = 20, n = 2×10⁷, r = 10, t = 14', | |
'sknuth_MaxOft with N = 40, n = 10⁷, r = 0, d = 10⁵, t = 8', | |
'sknuth_MaxOft with N = 30, n = 10⁷, r = 0, d = 10⁵, t = 16', | |
'sknuth_MaxOft with N = 20, n = 10⁷, r = 0, d = 10⁵, t = 24', | |
'sknuth_MaxOft with N = 20, n = 10⁷, r = 0, d = 10⁵, t = 32', | |
'svaria_SampleProd with N = 40, n = 10⁷, r = 0, t = 8', | |
'svaria_SampleProd with N = 20, n = 10⁷, r = 0, t = 16', | |
'svaria_SampleProd with N = 20, n = 10⁷, r = 0, t = 24', | |
'svaria_SampleMean with N = 2×10⁷, n = 30, r = 0', | |
'svaria_SampleMean with N = 2×10⁷, n = 30, r = 10', | |
'svaria_SampleCorr with N = 1, n = 2×10⁹, r = 0, k = 1', | |
'svaria_SampleCorr with N = 1, n = 2×10⁹, r = 0, k = 2', | |
'svaria_AppearanceSpacings with N = 1, Q = 10⁷, K = 10⁹, r = 0, s = 3, L = 15', | |
'svaria_AppearanceSpacings with N = 1, Q = 10⁷, K = 10⁹, r = 27, s = 3, L = 15', | |
'svaria_WeightDistrib with N = 1, n = 2×10⁷, r = 0, k = 2⁸, α = 0, β = 1⁄2²', | |
'svaria_WeightDistrib with N = 1, n = 2×10⁷, r = 20, k = 2⁸, α = 0, β = 1⁄2²', | |
'svaria_WeightDistrib with N = 1, n = 2×10⁷, r = 28, k = 2⁸, α = 0, β = 1⁄2²', | |
'svaria_WeightDistrib with N = 1, n = 2×10⁷, r = 0, k = 2⁸, α = 0, β = 1⁄2⁴', | |
'svaria_WeightDistrib with N = 1, n = 2×10⁷, r = 10, k = 2⁸, α = 0, β = 1⁄2⁴', | |
'svaria_WeightDistrib with N = 1, n = 2×10⁷, r = 26, k = 2⁸, α = 0, β = 1⁄2⁴', | |
'svaria_SumCollector with N = 1, n = 5×10⁸, r = 0, g = 10', | |
'smarsa_MatrixRank with N = 10, n = 10⁶, r = 0, s = 5, L = k = 30', | |
'smarsa_MatrixRank with N = 10, n = 10⁶, r = 25, s = 5, L = k = 30', | |
'smarsa_MatrixRank with N = 1, n = 5000, r = 0, s = 4, L = k = 1000', | |
'smarsa_MatrixRank with N = 1, n = 5000, r = 26, s = 4, L = k = 1000', | |
'smarsa_MatrixRank with N = 1, n = 80, r = 15, s = 15, L = k = 5000', | |
'smarsa_MatrixRank with N = 1, n = 80, r = 0, s = 30, L = k = 5000', | |
'smarsa_Savir2 with N = 10, n = 10⁷, r = 10, m = 2²⁰, t = 30', | |
'smarsa_GCD with N = 10, n = 5×10⁷, r = 0, s = 30', | |
'swalk_RandomWalk1 with N = 1, n = 10⁸, r = 0, s = 5, L0 = L1 = 50', | |
'swalk_RandomWalk1 with N = 1, n = 10⁸, r = 25, s = 5, L0 = L1 = 50', | |
'swalk_RandomWalk1 with N = 1, n = 10⁷, r = 0, s = 10, L0 = L1 = 1000', | |
'swalk_RandomWalk1 with N = 1, n = 10⁷, r = 20, s = 10, L0 = L1 = 1000', | |
'swalk_RandomWalk1 with N = 1, n = 10⁶, r = 0, s = 15, L0 = L1 = 10000', | |
'swalk_RandomWalk1 with N = 1, n = 10⁶, r = 15, s = 15, L0 = L1 = 10000', | |
'scomp_LinearComp with N = 1, n = 400000, r = 0, s = 1', | |
'scomp_LinearComp with N = 1, n = 400000, r = 29, s = 1', | |
'scomp_LempelZiv with N = 10, k = 27, r = 0, s = 30', | |
'scomp_LempelZiv with N = 10, k = 27, r = 15, s = 15', | |
'sspectral_Fourier3 with N = 100000, r = 0, s = 3, k = 14', | |
'sspectral_Fourier3 with N = 100000, r = 27, s = 3, k = 14', | |
'sstring_LongestHeadRun with N = 1, n = 1000, r = 0, s = 3, L = 10⁷', | |
'sstring_LongestHeadRun with N = 1, n = 1000, r = 27, s = 3, L = 10⁷', | |
'sstring_PeriodsInStrings with N = 10, n = 5×10⁸, r = 0, s = 10', | |
'sstring_PeriodsInStrings with N = 10, n = 5×10⁸, r = 20, s = 10', | |
'sstring_HammingWeight2 with N = 10, n = 10⁹, r = 0, s = 3, L = 10⁶', | |
'sstring_HammingWeight2 with N = 10, n = 10⁹, r = 27, s = 3, L = 10⁶', | |
'sstring_HammingCorr with N = 1, n = 10⁹, r = 10, s = 10, L = 30', | |
'sstring_HammingCorr with N = 1, n = 10⁸, r = 10, s = 10, L = 300', | |
'sstring_HammingCorr with N = 1, n = 10⁸, r = 10, s = 10, L = 1200', | |
'sstring_HammingIndep with N = 10, n = 3×10⁷, r = 0, s = 3, L = 30, d = 0', | |
'sstring_HammingIndep with N = 10, n = 3×10⁷, r = 27, s = 3, L = 30, d = 0', | |
'sstring_HammingIndep with N = 1, n = 3×10⁷, r = 0, s = 4, L = 300, d = 0', | |
'sstring_HammingIndep with N = 1, n = 3×10⁷, r = 26, s = 4, L = 300, d = 0', | |
'sstring_HammingIndep with N = 1, n = 1×10⁷, r = 0, s = 5, L = 1200, d = 0', | |
'sstring_HammingIndep with N = 1, n = 1×10⁷, r = 25, s = 5, L = 1200, d = 0', | |
'sstring_Run with N = 1, n = 2×10⁹, r = 0, s = 3', | |
'sstring_Run with N = 1, n = 2×10⁹, r = 27, s = 3', | |
'sstring_AutoCor with N = 10, n = 10⁹, r = 0, s = 3, d = 1', | |
'sstring_AutoCor with N = 10, n = 10⁹, r = 0, s = 3, d = 3', | |
'sstring_AutoCor with N = 10, n = 10⁹, r = 27, s = 3, d = 1', | |
'sstring_AutoCor with N = 10, n = 10⁹, r = 27, s = 3, d = 3', | |
]; | |
main(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment