Skip to content

Commit 7f7e168

Browse files
authored
Merge branch 'dev' into dev
2 parents 154d5a5 + 2de4c6b commit 7f7e168

44 files changed

Lines changed: 1917 additions & 1021 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/test-mlc-script-features.yml

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,81 @@ jobs:
156156
157157
print("\nAll process_mounts tests passed!")
158158
PYTEST
159+
- name: Test nested Docker opt-in mount handling
160+
shell: bash
161+
run: |
162+
python - <<'PY'
163+
import importlib.util
164+
import sys
165+
from types import SimpleNamespace
166+
from unittest.mock import patch
167+
168+
sys.path.insert(0, 'automation')
169+
170+
spec = importlib.util.spec_from_file_location(
171+
'run_docker_customize',
172+
'script/run-docker-container/customize.py'
173+
)
174+
mod = importlib.util.module_from_spec(spec)
175+
spec.loader.exec_module(mod)
176+
177+
logger_messages = []
178+
logger = SimpleNamespace(
179+
info=lambda *args, **kwargs: logger_messages.append(('info', args)),
180+
error=lambda *args, **kwargs: logger_messages.append(('error', args))
181+
)
182+
DOCKER_ENV_MARKER = '/.dockerenv'
183+
DOCKER_SOCKET = '/var/run/docker.sock'
184+
DOCKER_BIN = '/usr/bin/docker'
185+
186+
def run_case(enable_nested, docker_exit_code=0):
187+
captured = {'cmd': ''}
188+
189+
def fake_system(cmd):
190+
captured['cmd'] = cmd
191+
return docker_exit_code
192+
193+
def fake_exists(path):
194+
if path in [DOCKER_ENV_MARKER, DOCKER_SOCKET, DOCKER_BIN]:
195+
return True
196+
return False
197+
198+
env = {
199+
'MLC_CONTAINER_TOOL': 'docker',
200+
'MLC_DOCKER_RUN_SCRIPT_TAGS': 'run,docker,container',
201+
'MLC_DOCKER_RUN_CMD': 'echo nested-docker-ci-check',
202+
'MLC_DOCKER_ENABLE_NESTED': 'yes' if enable_nested else 'no'
203+
}
204+
i = {
205+
'os_info': {'platform': 'linux'},
206+
'env': env,
207+
'automation': SimpleNamespace(logger=logger)
208+
}
209+
210+
with patch.object(mod.os.path, 'exists', side_effect=fake_exists), \
211+
patch.object(mod.os, 'system', side_effect=fake_system), \
212+
patch.object(mod.shutil, 'which', return_value=DOCKER_BIN):
213+
result = mod.postprocess(i)
214+
215+
return result, captured['cmd']
216+
217+
enabled_result, enabled_cmd = run_case(True, docker_exit_code=0)
218+
disabled_result, disabled_cmd = run_case(False, docker_exit_code=0)
219+
failed_result, _ = run_case(True, docker_exit_code=1)
220+
221+
assert enabled_result['return'] == 0, enabled_result
222+
assert disabled_result['return'] == 0, disabled_result
223+
error_msg = failed_result.get('error', '').lower()
224+
assert failed_result['return'] == 1, failed_result
225+
assert 'docker' in error_msg, failed_result
226+
assert 'failed' in error_msg, failed_result
227+
228+
assert f'{DOCKER_SOCKET}:{DOCKER_SOCKET}' in enabled_cmd, enabled_cmd
229+
assert f'{DOCKER_BIN}:{DOCKER_BIN}' in enabled_cmd, enabled_cmd
230+
assert f'{DOCKER_SOCKET}:{DOCKER_SOCKET}' not in disabled_cmd, disabled_cmd
231+
assert f'{DOCKER_BIN}:{DOCKER_BIN}' not in disabled_cmd, disabled_cmd
232+
print('Nested Docker opt-in mount handling test passed')
233+
PY
159234
160235
test_experiment:
161236
runs-on: ${{ matrix.os }}

.github/workflows/test-mlperf-inference-resnet50.yml

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
name: MLPerf inference ResNet50
22

3+
permissions:
4+
contents: read
5+
36
on:
47
pull_request_target:
58
branches: [ "main", "dev" ]
@@ -107,4 +110,45 @@ jobs:
107110
git config --global credential.https://gist.github.com.helper ""
108111
git config --global credential.https://gist.github.com.helper "!gh auth git-credential"
109112
mlcr push,github,mlperf,inference,submission --repo_url=https://github.com/mlcommons/mlperf_inference_test_submissions_v5.0 --repo_branch=auto-update --commit_message="Results from R50 GH action on ${{ matrix.os }}" --quiet
113+
114+
mlc-run-rhel-docker:
115+
runs-on: ubuntu-latest
116+
env:
117+
MLC_INDEX: "on"
118+
steps:
119+
- uses: actions/checkout@v4
120+
with:
121+
fetch-depth: 0
122+
- name: Set up Python 3.12
123+
uses: actions/setup-python@v3
124+
with:
125+
python-version: "3.12"
126+
- name: Install mlcflow
127+
run: |
128+
pip install mlcflow
129+
pip install tabulate
130+
- name: Pull MLOps repo
131+
shell: bash
132+
env:
133+
REPO: ${{ github.event.pull_request.head.repo.html_url }}
134+
BRANCH: ${{ github.event.pull_request.head.ref }}
135+
run: |
136+
mlc pull repo "$REPO" --branch="$BRANCH"
137+
- name: Test MLPerf Inference ResNet50 (RHEL Docker)
138+
run: |
139+
mlcd run-mlperf,inference,_submission,_short,_r6.0-dev \
140+
--submitter="MLCommons" \
141+
--pull_changes=yes \
142+
--pull_inference_changes=yes \
143+
--hw_name="gh_rhel9_docker x86" \
144+
--model=resnet50 \
145+
--implementation=python \
146+
--backend=onnxruntime \
147+
--device=cpu \
148+
--scenario=Offline \
149+
--test_query_count=500 \
150+
--target_qps=1 \
151+
--docker_os=rhel \
152+
--docker_os_version=9 \
153+
-v --quiet
110154

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,10 @@ MANIFEST
55
__pycache__
66
develop-eggs/
77
dist/
8+
*.egg-info/
89
eggs/
910
.eggs/
11+
*.egg-info/
1012
lib/
1113
lib64/
1214
sdist/

automation/script/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -788,6 +788,7 @@ mlcr "app,mlperf,inference" --docker_run --docker_image_repo=myrepo --docker_reb
788788
3. **Mount Handling**: Host directories are automatically mounted into the container based on environment variable paths.
789789
4. **Environment Passing**: Host env variables (proxies, tokens, etc.) are passed into the container.
790790
5. **Execution**: The MLC run command is re-executed inside the container with `--docker_run_deps` to handle Docker-specific dependency installation.
791+
6. **Nested Docker Support**: Set `MLC_DOCKER_ENABLE_NESTED=yes` to mount Docker socket (`/var/run/docker.sock`) and Docker CLI binary into launched containers (when available) when MLC is running inside Docker.
791792

792793
### Docker Meta Configuration
793794

automation/script/docker.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,10 @@ def dockerfile(self_module, input_params):
2525
# Step 2: Process Dockerfile-related configurations
2626
env = input_params.get('env', {})
2727

28-
host_only_env_keys = [ "HOME", "USER" ]
28+
host_only_env_keys = ["HOME", "USER"]
2929
for key in host_only_env_keys:
3030
if key in env:
31-
del(env[key])
31+
del (env[key])
3232

3333
state_data = input_params.get('state', {})
3434
constant_vars = input_params.get('const', {})
@@ -141,8 +141,9 @@ def dockerfile(self_module, input_params):
141141
comments = []
142142

143143
# Push Docker image if specified
144-
if str(input_params.get('docker_push_image')
145-
).lower() in ['true', 'yes', '1']:
144+
docker_push_image = input_params.get(
145+
'docker_push_image', input_params.get('docker_upload', ''))
146+
if str(docker_push_image).lower() in ['true', 'yes', '1']:
146147
env['MLC_DOCKER_PUSH_IMAGE'] = 'yes'
147148

148149
dockerfile_env = docker_inputs.get('env')
@@ -229,10 +230,10 @@ def docker_run(self_module, i):
229230
show_time = i.get('show_time', False)
230231
logger = self_module.logger
231232
env = i.get('env', {})
232-
host_only_env_keys = [ "HOME", "USER" ]
233+
host_only_env_keys = ["HOME", "USER"]
233234
for key in host_only_env_keys:
234235
if key in env:
235-
del(env[key])
236+
del (env[key])
236237

237238
self_module.env = env
238239

automation/script/docker_utils.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@ def prepare_docker_inputs(input_params, docker_settings,
142142
"mlc_repos", "skip_mlc_sys_upgrade", "extra_sys_deps", "image_name",
143143
"gh_token", "fake_run_deps", "run_final_cmds", "real_run", "copy_files", "path", "user", "env", "build_env"
144144
]
145+
keys += ["cache", "split_mlc_run_cmd"]
145146

146147
if run_stage:
147148
keys += [

script/README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -923,6 +923,9 @@ This directory contains automation scripts for MLPerf benchmarks, AI/ML workflow
923923
- **[get-mlperf-training-src](get-mlperf-training-src/)**
924924
- get-mlperf-training-src
925925
- Tags: `get`, `src`, `source`, `training`, `training-src`, `training-source`, `mlperf`, `mlcommons`
926+
- **[get-mlperf-training-results-summary](get-mlperf-training-results-summary/)**
927+
- get-mlperf-training-results-summary
928+
- Tags: `get`, `mlperf`, `training`, `results`, `summary`, `summary-results`, `results-summary`
926929
- **[prepare-training-data-bert](prepare-training-data-bert/)**
927930
- prepare-training-data-bert
928931
- Tags: `prepare`, `mlperf`, `training`, `data`, `input`, `bert`

script/app-mlperf-inference-mlcommons-cpp/customize.py

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,8 @@ def preprocess(i):
7777
env['+ CXXFLAGS'].append("-std=c++14")
7878

7979
# add preprocessor flag like "#define MLC_MODEL_RESNET50"
80-
env['+ CXXFLAGS'].append('-DMLC_MODEL_' + env['MLC_MODEL'].upper().replace('-', '_').replace('.', '_'))
80+
env['+ CXXFLAGS'].append('-DMLC_MODEL_' +
81+
env['MLC_MODEL'].upper().replace('-', '_').replace('.', '_'))
8182
# add preprocessor flag like "#define MLC_MLPERF_BACKEND_ONNXRUNTIME"
8283
env['+ CXXFLAGS'].append('-DMLC_MLPERF_BACKEND_' +
8384
env['MLC_MLPERF_BACKEND'].upper())
@@ -90,7 +91,13 @@ def preprocess(i):
9091
import torch as _torch
9192
torch_path = os.path.dirname(_torch.__file__)
9293
torch_inc = os.path.join(torch_path, 'include')
93-
torch_inc_csrc = os.path.join(torch_path, 'include', 'torch', 'csrc', 'api', 'include')
94+
torch_inc_csrc = os.path.join(
95+
torch_path,
96+
'include',
97+
'torch',
98+
'csrc',
99+
'api',
100+
'include')
94101
torch_lib = os.path.join(torch_path, 'lib')
95102
env['+CPLUS_INCLUDE_PATH'].append(torch_inc)
96103
env['+CPLUS_INCLUDE_PATH'].append(torch_inc_csrc)
@@ -126,7 +133,6 @@ def preprocess(i):
126133
env['MLC_LINKER_LANG'] = 'CXX'
127134
env['MLC_RUN_DIR'] = os.getcwd()
128135

129-
130136
# For PyTorch backend, convert .pth weights to TorchScript .pt if needed
131137
if env.get('MLC_MLPERF_BACKEND', '') == 'pytorch':
132138
model_path = env.get('MLC_ML_MODEL_FILE_WITH_PATH', '')
@@ -135,9 +141,14 @@ def preprocess(i):
135141
if not os.path.exists(torchscript_path):
136142
import torch
137143
import torchvision.models as models
138-
logger.info(f"Converting {model_path} to TorchScript at {torchscript_path}")
144+
logger.info(
145+
f"Converting {model_path} to TorchScript at {torchscript_path}")
139146
model = models.resnet50()
140-
model.load_state_dict(torch.load(model_path, map_location='cpu', weights_only=False))
147+
model.load_state_dict(
148+
torch.load(
149+
model_path,
150+
map_location='cpu',
151+
weights_only=False))
141152
model.eval()
142153
traced = torch.jit.trace(model, torch.randn(1, 3, 224, 224))
143154
traced.save(torchscript_path)

0 commit comments

Comments
 (0)