mirror of
https://github.com/VolmitSoftware/Iris.git
synced 2026-10-11 19:14:11 +00:00
- Enable exact Rust Billow sampling and report the selected backend. - Add generation parity probes and native comparison tooling.
100 lines
5.6 KiB
Python
100 lines
5.6 KiB
Python
import argparse
|
|
import fcntl
|
|
import json
|
|
import os
|
|
from pathlib import Path
|
|
import statistics
|
|
import subprocess
|
|
import time
|
|
|
|
|
|
def fields(line):
|
|
return dict(part.split('=', 1) for part in line.split()[1:])
|
|
|
|
|
|
def main():
|
|
parser = argparse.ArgumentParser()
|
|
parser.add_argument('--pack', required=True)
|
|
parser.add_argument('--dimension', required=True)
|
|
parser.add_argument('--volmlib', required=True)
|
|
parser.add_argument('--seed', type=int, default=1337)
|
|
parser.add_argument('--center-x', type=int, default=2048)
|
|
parser.add_argument('--center-z', type=int, default=2048)
|
|
parser.add_argument('--warmup', type=int, default=64)
|
|
parser.add_argument('--measured', type=int, default=192)
|
|
parser.add_argument('--pairs', type=int, default=2)
|
|
parser.add_argument('--diagnostics', action='store_true')
|
|
parser.add_argument('--output', required=True)
|
|
args = parser.parse_args()
|
|
if args.pairs < 1:
|
|
parser.error('--pairs must be positive')
|
|
root = Path(__file__).resolve().parents[1]
|
|
output = Path(args.output).resolve()
|
|
if not any(output.is_relative_to(root / allowed) for allowed in ('.perf', 'build')):
|
|
parser.error('--output must be inside this checkout\'s .perf or build directory')
|
|
output.mkdir(parents=True, exist_ok=False)
|
|
environment = os.environ.copy()
|
|
environment.pop('GIT_CONFIG_COUNT', None)
|
|
for variable in ('JAVA_TOOL_OPTIONS', '_JAVA_OPTIONS', 'JDK_JAVA_OPTIONS'):
|
|
environment.pop(variable, None)
|
|
results = []
|
|
expected_hashes = None
|
|
with open('/tmp/iris-acceleration-integration-benchmark.lock', 'a') as lock:
|
|
print('Waiting for generation benchmark lock', flush=True)
|
|
fcntl.flock(lock, fcntl.LOCK_EX)
|
|
for pair in range(args.pairs):
|
|
for native in ([False, True] if pair % 2 == 0 else [True, False]):
|
|
backend = 'native' if native else 'java'
|
|
command = [str(root / 'gradlew'), ':probe:genProbe', '--no-daemon',
|
|
'-PincludeNativeBillow=true', f'-PlocalVolmLibDirectory={args.volmlib}',
|
|
f'-PprobePack={Path(args.pack).resolve()}', f'-PprobeDimension={args.dimension}',
|
|
f'-PprobeSeed={args.seed}', f'-PprobeCenterChunkX={args.center_x}',
|
|
f'-PprobeCenterChunkZ={args.center_z}', f'-PprobeWarmupChunks={args.warmup}',
|
|
f'-PprobeMeasuredChunks={args.measured}', '-PprobeMulticore=false',
|
|
'-PprobeStudio=false', f'-PprobeNativeBillow={str(native).lower()}',
|
|
'-PprobeNativeAccess=true',
|
|
f'-PprobeNativeDiagnostics={str(args.diagnostics).lower()}',
|
|
f'-PprobeRequireNativeSamples={str(native and args.diagnostics).lower()}',
|
|
f'-PprobeExpectedBackend={"native" if native else "java-disabled"}']
|
|
label = f'{pair + 1}-{backend}'
|
|
(output / f'{label}.command.json').write_text(json.dumps(command, indent=2) + '\n')
|
|
print(f'Running {label}', flush=True)
|
|
started = time.monotonic()
|
|
with (output / f'{label}.log').open('w') as log:
|
|
completed = subprocess.run(command, cwd=root, env=environment, stdout=log,
|
|
stderr=subprocess.STDOUT, check=False)
|
|
text = (output / f'{label}.log').read_text()
|
|
lines = text.splitlines()
|
|
hashes = [line for line in lines if line.startswith('GENPROBE_CHUNK_HASH ')]
|
|
result_lines = [line for line in lines if line.startswith('IRIS_GENPROBE_RESULT ')]
|
|
backend_lines = [line for line in lines if line.startswith('IRIS_GENPROBE_BACKEND ')]
|
|
if completed.returncode != 0 or len(result_lines) != 1 or len(backend_lines) != 1:
|
|
raise RuntimeError(f'{label} failed; see {output / (label + ".log")}')
|
|
result = fields(result_lines[0])
|
|
status = fields(backend_lines[0])
|
|
if result['status'] != 'PASS' or len(hashes) != args.warmup + args.measured:
|
|
raise RuntimeError(f'{label} did not generate every chunk successfully')
|
|
expected_backend = 'native' if native else 'java-disabled'
|
|
if status['status'] != expected_backend:
|
|
raise RuntimeError(f'{label} backend mismatch: {status}')
|
|
if expected_hashes is None:
|
|
expected_hashes = hashes
|
|
elif hashes != expected_hashes:
|
|
raise RuntimeError(f'{label} chunk block/biome hashes differ')
|
|
results.append({'pair': pair + 1, 'backend': backend, 'result': result,
|
|
'backend_status': status, 'wall_seconds': time.monotonic() - started})
|
|
(output / 'results.json').write_text(json.dumps(results, indent=2) + '\n')
|
|
rates = {backend: statistics.median(float(run['result']['measured_cps']) for run in results
|
|
if run['backend'] == backend) for backend in ('java', 'native')}
|
|
summary = {'median_chunks_per_second': rates,
|
|
'native_throughput_change_percent': (rates['native'] / rates['java'] - 1) * 100,
|
|
'all_chunk_hashes_equal': True, 'diagnostics_enabled': args.diagnostics,
|
|
'run_count': len(results), 'seed': args.seed,
|
|
'unique_chunks': args.warmup + args.measured}
|
|
(output / 'summary.json').write_text(json.dumps(summary, indent=2) + '\n')
|
|
print(json.dumps(summary, indent=2))
|
|
|
|
|
|
if __name__ == '__main__':
|
|
main()
|