Skip to content

Commit 280c08f

Browse files
authored
#283: Added GPU Support for run-db-test (#287)
fixes #283
1 parent ac14bfc commit 280c08f

File tree

14 files changed

+424
-165
lines changed

14 files changed

+424
-165
lines changed

.github/workflows/gpu-tests.yml

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
name: GPU Tests
2+
3+
on:
4+
workflow_call:
5+
6+
jobs:
7+
8+
prep-testbed-gpu:
9+
runs-on: ubuntu-24.04
10+
11+
steps:
12+
- uses: actions/checkout@v4
13+
14+
- name: Setup Python & Poetry Environment
15+
uses: exasol/python-toolbox/.github/actions/[email protected]
16+
17+
- id: set-matrix
18+
run: |
19+
ALL_TESTS=`poetry run -- nox -s integration-test-list -- --test-set gpu-only`
20+
echo "matrix=$ALL_TESTS" >> "$GITHUB_OUTPUT"
21+
outputs:
22+
matrix: ${{ steps.set-matrix.outputs.matrix }}
23+
24+
test-gpu:
25+
needs: prep-testbed-gpu
26+
strategy:
27+
fail-fast: false
28+
matrix:
29+
python_version:
30+
- "3.10"
31+
test-path: ${{fromJson(needs.prep-testbed-gpu.outputs.matrix)}}
32+
runs-on:
33+
labels: int-linux-x64-4core-gpu-t4-ubuntu24.04-1
34+
name: GPU Test
35+
steps:
36+
- uses: actions/checkout@v4
37+
38+
#Cannot use exasol/python-toolbox/.github/actions/python-environment here
39+
#because pipx is not installed on int-linux-x64-4core-gpu-t4-ubuntu24.04-1
40+
- name: Setup Python ('${{ matrix.python_version }}')
41+
uses: actions/setup-python@v5
42+
with:
43+
python-version: '${{ matrix.python_version }}'
44+
45+
- name: Install pipx and poetry
46+
run: |
47+
pip install pipx
48+
pipx install poetry=="2.1.2"
49+
echo "$HOME/.local/bin" >> $GITHUB_PATH
50+
51+
- name: Setup Poetry
52+
run: |
53+
poetry env use python3
54+
poetry install
55+
56+
- name: Allow unprivileged user namespaces
57+
run: sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=0
58+
59+
- name: Run ${{ matrix.test-path.name }}
60+
run: poetry run -- python "${{ matrix.test-path.path }}"
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
name: Integration Tests
2+
3+
on:
4+
workflow_call:
5+
secrets:
6+
DOCKER_USERNAME:
7+
required: true
8+
DOCKER_PASSWORD:
9+
required: true
10+
jobs:
11+
12+
prep-testbed:
13+
runs-on: ubuntu-24.04
14+
15+
steps:
16+
- uses: actions/checkout@v4
17+
18+
- name: Setup Python & Poetry Environment
19+
uses: exasol/python-toolbox/.github/actions/[email protected]
20+
21+
- id: set-matrix
22+
run: |
23+
ALL_TESTS=`poetry run -- nox -s integration-test-list -- --test-set default`
24+
echo "matrix=$ALL_TESTS" >> "$GITHUB_OUTPUT"
25+
outputs:
26+
matrix: ${{ steps.set-matrix.outputs.matrix }}
27+
28+
test-all:
29+
needs: prep-testbed
30+
strategy:
31+
fail-fast: false
32+
matrix:
33+
python_version:
34+
- "3.10"
35+
test-path: ${{fromJson(needs.prep-testbed.outputs.matrix)}}
36+
runs-on: ubuntu-24.04
37+
name: ${{ matrix.test-path.name }}
38+
steps:
39+
- uses: actions/checkout@v4
40+
41+
- name: Setup Python & Poetry Environment
42+
uses: exasol/python-toolbox/.github/actions/[email protected]
43+
with:
44+
python-version: '${{ matrix.python_version }}'
45+
46+
- name: Allow unprivileged user namespaces
47+
run: sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=0
48+
49+
- name: Run test ${{ matrix.test-path.name }}
50+
run: poetry run -- python ${{ matrix.test-path.path }}
51+
env: # Set the secret as an input
52+
DOCKER_USER: ${{ secrets.DOCKER_USERNAME }}
53+
DOCKER_PASSWD: ${{ secrets.DOCKER_PASSWORD }}

.github/workflows/slow-checks.yml

Lines changed: 10 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -27,46 +27,15 @@ jobs:
2727
- name: Tests
2828
run: echo "Slow tests approved"
2929

30-
prep-testbed:
31-
needs: slow-tests-approval
32-
runs-on: ubuntu-24.04
33-
34-
steps:
35-
- uses: actions/checkout@v4
36-
37-
- name: Setup Python & Poetry Environment
38-
uses: exasol/python-toolbox/.github/actions/[email protected]
39-
40-
- id: set-matrix
41-
run: |
42-
ALL_TESTS=`poetry run -- nox -s integration-test-list`
43-
echo "matrix=$ALL_TESTS" >> "$GITHUB_OUTPUT"
44-
outputs:
45-
matrix: ${{ steps.set-matrix.outputs.matrix }}
4630

47-
test-all:
48-
needs: prep-testbed
49-
strategy:
50-
fail-fast: false
51-
matrix:
52-
python_version:
53-
- "3.10"
54-
test-path: ${{fromJson(needs.prep-testbed.outputs.matrix)}}
55-
runs-on: ubuntu-24.04
56-
name: ${{ matrix.test-path.name }}
57-
steps:
58-
- uses: actions/checkout@v4
59-
60-
- name: Setup Python & Poetry Environment
61-
uses: exasol/python-toolbox/.github/actions/[email protected]
62-
with:
63-
python-version: '${{ matrix.python_version }}'
64-
65-
- name: Allow unprivileged user namespaces
66-
run: sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=0
31+
integration-tests:
32+
needs: slow-tests-approval
33+
name: Integrations
34+
uses: ./.github/workflows/integration-tests.yml
35+
secrets: inherit
6736

68-
- name: Run test ${{ matrix.test-path.name }}
69-
run: poetry run -- python ${{ matrix.test-path.path }}
70-
env: # Set the secret as an input
71-
DOCKER_USER: ${{ secrets.DOCKER_USERNAME }}
72-
DOCKER_PASSWD: ${{ secrets.DOCKER_PASSWORD }}
37+
gpu-tests:
38+
needs: slow-tests-approval
39+
name: Integrations
40+
uses: ./.github/workflows/gpu-tests.yml
41+
secrets: inherit

doc/changes/unreleased.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,7 @@
66

77
## Refactorings
88
- #252: Update Github workflows from Exasol toolbox
9+
10+
## Features
11+
12+
- #283: Added GPU Support for `run-db-test`

doc/user_guide/user_guide.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,13 @@ With this additional option, `exaslct` won't build and export the container agai
154154
1. `exaslct` won't check if the given container file is compatible with the given flavor path. If this is not the case, the tests probably will fail.
155155
2. As `exaslct` cannot check if the file was changed during different executions of `run-db-test` with options `--reuse-uploaded-container` or `--reuse-test-environment`, `exaslct` will always skip the upload if those options are set and the file already exists in BucketFS.
156156

157+
### Testing with an accelerator
158+
159+
If your test environment fulfills the requirements, you can run tests with an accelerator. Currently, only `nvidia` is supported:
160+
```bash
161+
exaslct run-db-test --flavor-path=flavors/<flavor-name> --accelerator nvidia
162+
```
163+
This will launch the underlying docker-db with the necessary options to enable the `NVIDIA` accelerator.
157164

158165
## Cleaning up after you are finished
159166

exasol/slc/api/run_db_tests.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
from exasol.slc.internal.tasks.test.test_container_content import (
3636
build_test_container_content,
3737
)
38+
from exasol.slc.models.accelerator import Accelerator, defaultAccelerator
3839
from exasol.slc.models.compression_strategy import (
3940
CompressionStrategy,
4041
defaultCompressionStrategy,
@@ -103,6 +104,7 @@ def run_db_test(
103104
log_level: Optional[str] = None,
104105
use_job_specific_log_file: bool = True,
105106
compression_strategy: CompressionStrategy = defaultCompressionStrategy(),
107+
accelerator: Accelerator = defaultAccelerator(),
106108
) -> AllTestsResult:
107109
"""
108110
This command runs the integration tests in local docker-db.
@@ -155,6 +157,12 @@ def run_db_test(
155157
if external_exasol_ssh_port is None:
156158
raise api_errors.MissingArgumentError("external_exasol_ssh_port")
157159

160+
docker_runtime = None
161+
if accelerator == Accelerator.NVIDA:
162+
additional_db_parameter += ("-enableAcceleratorDeviceDetection=1",)
163+
docker_runtime = "nvidia"
164+
docker_environment_variable += ("NVIDIA_VISIBLE_DEVICES=all",)
165+
158166
def root_task_generator() -> DependencyLoggerBaseTask:
159167
return generate_root_task(
160168
task_class=TestContainer,
@@ -199,6 +207,7 @@ def root_task_generator() -> DependencyLoggerBaseTask:
199207
additional_db_parameter=additional_db_parameter,
200208
test_container_content=build_test_container_content(test_container_folder),
201209
compression_strategy=compression_strategy,
210+
docker_runtime=docker_runtime,
202211
docker_environment_variables=docker_environment_variable,
203212
)
204213

exasol/slc/models/accelerator.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
from enum import Enum
2+
from typing import List
3+
4+
5+
class Accelerator(Enum):
6+
"""
7+
This enum serves as a definition of values for possible accelerators for `run-db-tests`.
8+
"""
9+
10+
NONE = "none"
11+
NVIDA = "nvidia"
12+
13+
14+
def defaultAccelerator() -> Accelerator:
15+
return Accelerator.NONE
16+
17+
18+
def acceleratorValues() -> List[str]:
19+
return [a.value for a in Accelerator]

exasol/slc/tool/commands/run_db_tests.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,11 @@
2525

2626
from exasol.slc import api
2727
from exasol.slc.api import api_errors
28+
from exasol.slc.models.accelerator import (
29+
Accelerator,
30+
acceleratorValues,
31+
defaultAccelerator,
32+
)
2833
from exasol.slc.models.compression_strategy import CompressionStrategy
2934
from exasol.slc.tool.cli import cli
3035
from exasol.slc.tool.options.export_options import export_options
@@ -149,6 +154,13 @@
149154
@add_options(system_options)
150155
@add_options(luigi_logging_options)
151156
@add_options(export_options)
157+
@click.option(
158+
"--accelerator",
159+
type=click.Choice(acceleratorValues()),
160+
show_default=True,
161+
default=defaultAccelerator().value,
162+
help=f"""Accelerator to be enabled for tests in docker-db. Possible values: {acceleratorValues()}""",
163+
)
152164
def run_db_test(
153165
flavor_path: Tuple[str, ...],
154166
release_goal: Tuple[str, ...],
@@ -209,6 +221,7 @@ def run_db_test(
209221
log_level: Optional[str],
210222
use_job_specific_log_file: bool,
211223
compression_strategy: str,
224+
accelerator: str,
212225
):
213226
"""
214227
This command runs the integration tests in local docker-db.
@@ -279,6 +292,7 @@ def run_db_test(
279292
use_job_specific_log_file=use_job_specific_log_file,
280293
compression_strategy=CompressionStrategy[compression_strategy.upper()],
281294
docker_environment_variable=docker_environment_variable,
295+
accelerator=Accelerator[accelerator.upper()],
282296
)
283297
if result.command_line_output_path.exists():
284298
with result.command_line_output_path.open("r") as f:

noxfile.py

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
import json
2+
from argparse import ArgumentParser
3+
from enum import Enum
24

35
import nox
46

@@ -11,11 +13,38 @@
1113
from noxconfig import PROJECT_CONFIG
1214

1315

16+
class TestSet(Enum):
17+
GPU_ONLY = "gpu-only"
18+
DEFAULT = "default"
19+
20+
1421
@nox.session(name="integration-test-list", python=False)
1522
def run_integration_test_list(session: nox.Session):
1623
"""
1724
Returns the test files under directory test (without walking subdirectories) as JSON list.
1825
"""
26+
test_set_values = [ts.value for ts in TestSet]
27+
parser = ArgumentParser(
28+
usage=f"nox -s {session.name} -- --test-set {{{','.join(test_set_values)}}}"
29+
)
30+
parser.add_argument(
31+
"--test-set",
32+
type=TestSet,
33+
required=True,
34+
help="Test set name",
35+
)
36+
args = parser.parse_args(session.posargs)
1937
test_path = PROJECT_CONFIG.root / "test"
20-
tests = [{"path": str(t), "name": t.stem} for t in test_path.glob("test_*.py")]
38+
if args.test_set == TestSet.GPU_ONLY:
39+
tests = [
40+
{"path": str(t), "name": t.stem}
41+
for t in test_path.glob("test_*.py")
42+
if "gpu" in t.name
43+
]
44+
else:
45+
tests = [
46+
{"path": str(t), "name": t.stem}
47+
for t in test_path.glob("test_*.py")
48+
if "gpu" not in t.name
49+
]
2150
print(json.dumps(tests))

0 commit comments

Comments
 (0)