Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,6 @@ optional-dependencies.quartus-report = [ "calmjs-parse", "tabulate" ]
optional-dependencies.sr = [ "sympy>=1.13.1" ]
optional-dependencies.testing = [
"calmjs-parse",
"hgq>=0.2.3",
"onnx>=1.4",
"pytest",
"pytest-cov",
Expand All @@ -64,6 +63,17 @@ optional-dependencies.testing = [
"tabulate",
"torch",
]
optional-dependencies.testing-keras2 = [
"hgq>=0.2.3",
"qkeras",
"tensorflow>=2.8,<=2.14.1",
]
optional-dependencies.testing-keras3 = [
"da4ml",
"hgq2>=0.0.1",
"keras>=3.10",
"tensorflow>=2.15",
]
urls.Homepage = "https://fastmachinelearning.org/hls4ml"
scripts.hls4ml = "hls4ml.cli:main"
entry-points.pytest_randomly.random_seeder = "hls4ml:reseed"
Expand Down
15 changes: 12 additions & 3 deletions test/pytest/ci-template.yml
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
.pytest:
stage: test
image: gitlab-registry.cern.ch/fastmachinelearning/hls4ml-testing:0.6.2.base
image: gitlab-registry.cern.ch/fastmachinelearning/hls4ml-testing:0.6.3.base
tags:
- k8s-default
variables:
CONDA_ENV: "hls4ml-testing"
EXTRA_DEPS: "[da,testing,testing-keras2,sr,optimization]"
before_script:
- eval "$(conda shell.bash hook)"
- conda activate hls4ml-testing
- conda activate "$CONDA_ENV"
- git config --global --add safe.directory /builds/fastmachinelearning/hls4ml
- git submodule update --init --recursive hls4ml/templates/catapult/
- if [ $EXAMPLEMODEL == 1 ]; then git submodule update --init example-models; fi
- pip install .[da,testing,sr,optimization]
- pip install .${EXTRA_DEPS}

# set up vivado_hls command
- mkdir -p cmd_vivado_${VIVADO_VERSION}
Expand Down Expand Up @@ -41,3 +44,9 @@
paths:
- test/pytest/hls4mlprj*.tar.gz
- test/pytest/synthesis_report_*.json

.pytest-keras3-only:
extends: .pytest
variables:
CONDA_ENV: "hls4ml-testing-keras3"
EXTRA_DEPS: "[da,testing,testing-keras3,sr]"
26 changes: 21 additions & 5 deletions test/pytest/generate_ci_yaml.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

template = """
pytest.{}:
extends: .pytest
extends: {}
variables:
PYTESTFILE: {}
EXAMPLEMODEL: {}
Expand All @@ -28,6 +28,7 @@

# Long-running tests will not be bundled with other tests
LONGLIST = {'test_hgq_layers', 'test_hgq_players', 'test_qkeras', 'test_pytorch_api'}
KERAS3_LIST = {'test_keras_v3_api', 'test_hgq2_mha', 'test_einsum_dense', 'test_qeinsum', 'test_multiout_onnx'}

# Test files to split by individual test cases
# Value = chunk size per CI job
Expand Down Expand Up @@ -71,7 +72,7 @@ def generate_test_yaml(test_root='.'):
test_paths = [
path
for path in test_root.glob('**/test_*.py')
if path.stem not in (BLACKLIST | LONGLIST | set(SPLIT_BY_TEST_CASE.keys()))
if path.stem not in (BLACKLIST | LONGLIST | set(SPLIT_BY_TEST_CASE.keys()) | KERAS3_LIST)
]
need_example_models = [uses_example_model(path) for path in test_paths]

Expand All @@ -85,7 +86,7 @@ def generate_test_yaml(test_root='.'):
name = '+'.join(names)
test_files = ' '.join([str(path.relative_to(test_root)) for path in batch_paths])
batch_need_example_model = int(any([need_example_models[i] for i in batch_idxs]))
diff_yml = yaml.safe_load(template.format(name, test_files, batch_need_example_model))
diff_yml = yaml.safe_load(template.format(name, '.pytest', test_files, batch_need_example_model))
if yml is None:
yml = diff_yml
else:
Expand All @@ -96,7 +97,7 @@ def generate_test_yaml(test_root='.'):
name = path.stem.replace('test_', '')
test_file = str(path.relative_to(test_root))
needs_examples = uses_example_model(path)
diff_yml = yaml.safe_load(template.format(name, test_file, int(needs_examples)))
diff_yml = yaml.safe_load(template.format(name, '.pytest', test_file, int(needs_examples)))
yml.update(diff_yml)

test_paths = [path for path in test_root.glob('**/test_*.py') if path.stem in SPLIT_BY_TEST_CASE]
Expand All @@ -111,12 +112,27 @@ def generate_test_yaml(test_root='.'):
for i, batch in enumerate(batched(test_ids, chunk_size)):
job_name = f'{name_base}_part{i}'
test_file_args = ' '.join(batch).strip().replace('\n', ' ')
diff_yml = yaml.safe_load(template.format(job_name, test_file_args, int(needs_examples)))
diff_yml = yaml.safe_load(template.format(job_name, '.pytest', test_file_args, int(needs_examples)))
if yml is None:
yml = diff_yml
else:
yml.update(diff_yml)

keras3_paths = [path for path in test_root.glob('**/test_*.py') if path.stem in KERAS3_LIST]
keras3_need_examples = [uses_example_model(path) for path in keras3_paths]

k3_idxs = list(range(len(keras3_need_examples)))
k3_idxs = sorted(k3_idxs, key=lambda i: f'{keras3_need_examples[i]}_{path_to_name(keras3_paths[i])}')

for batch_idxs in batched(k3_idxs, n_test_files_per_yml):
batch_paths: list[Path] = [keras3_paths[i] for i in batch_idxs]
names = [path_to_name(path) for path in batch_paths]
name = 'keras3-' + '+'.join(names)
test_files = ' '.join([str(path.relative_to(test_root)) for path in batch_paths])
batch_need_example_model = int(any([keras3_need_examples[i] for i in batch_idxs]))
diff_yml = yaml.safe_load(template.format(name, '.pytest-keras3-only', test_files, batch_need_example_model))
yml.update(diff_yml)

return yml


Expand Down
4 changes: 3 additions & 1 deletion test/pytest/test_hgq2_mha.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,16 @@

if keras.__version__ < '3.0.0':
pytest.skip('This test requires keras 3.0.0 or higher', allow_module_level=True)

import numpy as np
from hgq.config import QuantizerConfigScope
from hgq.layers import QMultiHeadAttention
from hgq.utils import trace_minmax

from hls4ml.converters import convert_from_keras_model

# Current hgq2 release rejects the parallelization_factor kwarg that hls4ml passes; skip until supported.
pytest.skip('Skip until hgq2 supports parallelization_factor in QEinsumDense', allow_module_level=True)

test_path = Path(__file__).parent


Expand Down
Loading