Skip to content

Commit 744cbba

Browse files
committed
[query] Various Benchmark Suite Improvements
1 parent 858f3ab commit 744cbba

File tree

14 files changed

+388
-338
lines changed

14 files changed

+388
-338
lines changed

hail/python/benchmark/conftest.py

Lines changed: 34 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
def pytest_addoption(parser):
1313
parser.addoption("--log", type=str, help='Log file path', default=None)
1414
parser.addoption("--output", type=str, help="Output file path.", default=None)
15-
parser.addoption("--data-dir", type=str, help="Data directory.", default=None)
15+
parser.addoption("--data-dir", type=str, help="Data directory.", default=os.getenv('HAIL_BENCHMARK_DIR'))
1616
parser.addoption('--iterations', type=int, help='override number of iterations for all benchmarks', default=None)
1717
parser.addoption('--cores', type=int, help='Number of cores to use.', default=1)
1818
parser.addoption(
@@ -23,36 +23,42 @@ def pytest_addoption(parser):
2323
const='cpu',
2424
default=None,
2525
)
26-
parser.addoption('--profiler-path', type=str, help='path to aysnc profiler', default=None)
26+
parser.addoption(
27+
'--max-duration',
28+
type=int,
29+
help='Maximum permitted duration for any benchmark trial in seconds, not to be confused with pytest-timeout',
30+
default=200,
31+
)
32+
parser.addoption('--max-failures', type=int, help='Stop benchmarking item after this many failures', default=3)
33+
parser.addoption(
34+
'--profiler-path', type=str, help='path to aysnc profiler', default=os.getenv('ASYNC_PROFILER_HOME')
35+
)
2736
parser.addoption('--profiler-fmt', choices=['html', 'flame', 'jfr'], help='Choose profiler output.', default='html')
2837

2938

30-
def run_config_from_pytest_config(pytest_config):
31-
return type(
32-
'RunConfig',
33-
(object,),
34-
{
35-
**{
36-
flag: pytest_config.getoption(flag) or default
37-
for flag, default in [
38-
('log', None),
39-
('output', None),
40-
('cores', 1),
41-
('data_dir', os.getenv('HAIL_BENCHMARK_DIR')),
42-
('iterations', None),
43-
('profile', None),
44-
('profiler_path', os.getenv('ASYNC_PROFILER_HOME')),
45-
('profiler_fmt', None),
46-
]
47-
},
48-
'verbose': pytest_config.getoption('verbose') > 0,
49-
'quiet': pytest_config.getoption('verbose') < 0,
50-
'timeout': int(pytest_config.getoption('timeout') or 1800),
51-
},
39+
@pytest.hookimpl
40+
def pytest_configure(config):
41+
init_logging(file=config.getoption('log'))
42+
43+
44+
@pytest.hookimpl(tryfirst=True)
45+
def pytest_collection_modifyitems(config, items):
46+
max_duration = config.getoption('max_duration')
47+
48+
xfail = pytest.mark.xfail(
49+
raises=TimeoutError,
50+
reason=f'Runtime exceeds maximum permitted duration of {max_duration}s',
5251
)
5352

53+
benchmark_items = []
54+
for item in items:
55+
if item.name.startswith('benchmark_'):
56+
benchmark_items.append(item)
5457

55-
@pytest.hookimpl
56-
def pytest_configure(config):
57-
config.run_config = run_config_from_pytest_config(config)
58-
init_logging(file=config.run_config.log)
58+
if (xtimeout := item.get_closest_marker('xtimeout')) is None:
59+
continue
60+
61+
if len(xtimeout.args) == 0 or (len(xtimeout.args) == 1 and xtimeout.args[0] >= max_duration):
62+
item.add_marker(xfail)
63+
64+
items[:] = benchmark_items

hail/python/benchmark/hail/benchmark_combiner.py

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
from test.hail.helpers import with_flags
33

44
import hail as hl
5-
from benchmark.tools import benchmark, chunk
5+
from benchmark.tools import chunk
66
from hail.vds.combiner import combine_variant_datasets, new_combiner, transform_gvcf
77

88
COMBINE_GVCF_MAX = 100
@@ -13,7 +13,7 @@ def import_vcf(path):
1313
return hl.import_vcf(str(path), reference_genome='GRCh38', force=True)
1414

1515

16-
@benchmark()
16+
@pytest.mark.xfail(raises=hl.utils.java.FatalError, reason='??')
1717
@with_flags(no_ir_logging='1')
1818
def benchmark_compile_2k_merge(empty_gvcf, tmp_path):
1919
vcf = import_vcf(empty_gvcf)
@@ -22,29 +22,26 @@ def benchmark_compile_2k_merge(empty_gvcf, tmp_path):
2222
hl.vds.write_variant_datasets(combined, str(tmp_path / 'combiner-multi-write'), overwrite=True)
2323

2424

25-
@benchmark()
25+
@pytest.mark.xtimeout(270)
2626
def benchmark_python_only_10k_transform(empty_gvcf):
2727
for vcf in [import_vcf(empty_gvcf)] * 10_000:
2828
transform_gvcf(vcf, [])
2929

3030

31-
@benchmark()
3231
def benchmark_python_only_10k_combine(empty_gvcf):
3332
vcf = import_vcf(empty_gvcf)
3433
mt = transform_gvcf(vcf, [])
3534
for mts in chunk(COMBINE_GVCF_MAX, [mt] * 10_000):
3635
combine_variant_datasets(mts)
3736

3837

39-
@benchmark()
4038
def benchmark_import_and_transform_gvcf(single_gvcf):
4139
mt = import_vcf(single_gvcf)
4240
vds = transform_gvcf(mt, [])
4341
vds.reference_data._force_count_rows()
4442
vds.variant_data._force_count_rows()
4543

4644

47-
@benchmark()
4845
def benchmark_import_gvcf_force_count(single_gvcf):
4946
mt = import_vcf(single_gvcf)
5047
mt._force_count_rows()
@@ -59,14 +56,14 @@ def tmp_and_output_paths(tmp_path):
5956
return (tmp, output)
6057

6158

62-
@benchmark()
59+
@pytest.mark.xtimeout(180)
6360
def benchmark_vds_combiner_chr22(chr22_gvcfs, tmp_and_output_paths):
6461
parts = hl.eval([hl.parse_locus_interval('chr22:start-end', reference_genome='GRCh38')])
65-
62+
tmp, output = tmp_and_output_paths
6663
combiner = new_combiner(
67-
output_path=str(tmp_and_output_paths[0]),
64+
output_path=str(output),
6865
intervals=parts,
69-
temp_path=str(tmp_and_output_paths[1]),
66+
temp_path=str(tmp),
7067
gvcf_paths=[str(path) for path in chr22_gvcfs],
7168
reference_genome='GRCh38',
7269
branch_factor=16,

hail/python/benchmark/hail/benchmark_linalg.py

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,45 @@
1+
import pytest
2+
13
import hail as hl
2-
from benchmark.tools import benchmark
34

45

5-
@benchmark()
6+
@pytest.mark.xtimeout
67
def benchmark_block_matrix_nested_multiply(tmp_path):
78
bm = hl.linalg.BlockMatrix.random(8 * 1024, 8 * 1024)
89
bm = bm.checkpoint(str(tmp_path / 'checkpoint.mt'))
910
bm = (bm @ bm) @ bm @ bm @ (bm @ bm)
1011
bm.write(str(tmp_path / 'result.mt'), overwrite=True)
1112

1213

13-
@benchmark()
1414
def benchmark_make_ndarray():
1515
ht = hl.utils.range_table(200_000)
1616
ht = ht.annotate(x=hl.nd.array(hl.range(ht.idx)))
1717
ht._force_count()
1818

1919

20-
@benchmark()
2120
def benchmark_ndarray_addition():
2221
arr = hl.nd.ones((1024, 1024))
2322
hl.eval(arr + arr)
2423

2524

26-
@benchmark()
2725
def benchmark_ndarray_matmul_int64():
2826
arr = hl.nd.arange(1024 * 1024).map(hl.int64).reshape((1024, 1024))
2927
hl.eval(arr @ arr)
3028

3129

32-
@benchmark()
3330
def benchmark_ndarray_matmul_float64():
3431
arr = hl.nd.arange(1024 * 1024).map(hl.float64).reshape((1024, 1024))
3532
hl.eval(arr @ arr)
3633

3734

38-
@benchmark()
35+
@pytest.mark.xtimeout(200)
3936
def benchmark_blockmatrix_write_from_entry_expr_range_mt(tmp_path):
4037
mt = hl.utils.range_matrix_table(40_000, 40_000, n_partitions=4)
4138
path = str(tmp_path / 'result.bm')
4239
hl.linalg.BlockMatrix.write_from_entry_expr(mt.row_idx + mt.col_idx, path)
4340

4441

45-
@benchmark()
42+
@pytest.mark.xtimeout(700)
4643
def benchmark_blockmatrix_write_from_entry_expr_range_mt_standardize(tmp_path):
4744
mt = hl.utils.range_matrix_table(40_000, 40_000, n_partitions=4)
4845
path = str(tmp_path / 'result.bm')
@@ -51,20 +48,19 @@ def benchmark_blockmatrix_write_from_entry_expr_range_mt_standardize(tmp_path):
5148
)
5249

5350

54-
@benchmark()
5551
def benchmark_sum_table_of_ndarrays():
5652
ht = hl.utils.range_table(400).annotate(nd=hl.nd.ones((4096, 4096)))
5753
ht.aggregate(hl.agg.ndarray_sum(ht.nd))
5854

5955

60-
@benchmark()
56+
@pytest.mark.xtimeout(250)
6157
def benchmark_block_matrix_to_matrix_table_row_major():
6258
mt = hl.utils.range_matrix_table(20_000, 20_000, n_partitions=4)
6359
bm = hl.linalg.BlockMatrix.from_entry_expr(mt.row_idx + mt.col_idx)
6460
bm.to_matrix_table_row_major()._force_count_rows()
6561

6662

67-
@benchmark()
63+
@pytest.mark.xtimeout
6864
def benchmark_king(tmp_path):
6965
mt = hl.balding_nichols_model(6, n_variants=10000, n_samples=4096)
7066
path = str(tmp_path / 'result.mt')

0 commit comments

Comments
 (0)