Skip to content
Open
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
14 changes: 12 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -55,15 +55,25 @@ 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<9",
"pytest-cov",
"pytest-randomly",
"qonnx",
"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,16 +1,19 @@
.pytest:
stage: test
image: gitlab-registry.cern.ch/fastmachinelearning/hls4ml-testing:0.6.1.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"
- source /opt/intel/oneapi/setvars.sh --force
- 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}
script:
- cd test/pytest
- pytest $PYTESTFILE -rA --cov-report xml --cov-report term --cov=hls4ml --junitxml=report.xml --randomly-seed=42 --randomly-dont-reorganize --randomly-dont-reset-seed
Expand All @@ -24,3 +27,9 @@
path: test/pytest/coverage.xml
paths:
- test/pytest/hls4mlprj*.tar.gz

.pytest-keras3-only:
extends: .pytest
variables:
CONDA_ENV: "hls4ml-testing-keras3"
EXTRA_DEPS: "[da,testing,testing-keras3,sr]"
24 changes: 20 additions & 4 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 @@ -26,6 +26,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'}


def path_to_name(test_path):
Expand All @@ -48,7 +49,7 @@ def uses_example_model(test_filename):

def generate_test_yaml(test_root='.'):
test_root = Path(test_root)
test_paths = [path for path in test_root.glob('**/test_*.py') if path.stem not in (BLACKLIST | LONGLIST)]
test_paths = [path for path in test_root.glob('**/test_*.py') if path.stem not in (BLACKLIST | LONGLIST | KERAS3_LIST)]
need_example_models = [uses_example_model(path) for path in test_paths]

idxs = list(range(len(need_example_models)))
Expand All @@ -61,7 +62,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 @@ -72,7 +73,22 @@ 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)

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