Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
tsoc
superbenchmark
Commits
a10c3e15
Commit
a10c3e15
authored
Apr 01, 2026
by
one
Browse files
Refactor environment variable handling in runner.py
parent
325db60e
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
114 additions
and
7 deletions
+114
-7
superbench/runner/runner.py
superbench/runner/runner.py
+62
-7
tests/runner/test_runner.py
tests/runner/test_runner.py
+52
-0
No files found.
superbench/runner/runner.py
View file @
a10c3e15
...
...
@@ -193,16 +193,67 @@ class SuperBenchRunner():
','
.
join
(
f
'
{
host
}
:
{
mode
.
proc_num
}
'
for
host
in
mode
.
host_list
),
bind_to
=
mode
.
bind_to
,
mca_list
=
' '
.
join
(
f
'-mca
{
k
}
{
v
}
'
for
k
,
v
in
mode
.
mca
.
items
()),
env_list
=
' '
.
join
(
f
'-x
{
k
}
=
{
str
(
v
).
format
(
proc_rank
=
mode
.
proc_rank
,
proc_num
=
mode
.
proc_num
)
}
'
if
isinstance
(
v
,
str
)
else
f
'-x
{
k
}
'
for
k
,
v
in
mode
.
env
.
items
()
),
env_list
=
' '
.
join
(
self
.
__format_mpi_env_args
(
mode
.
env
,
mode
.
proc_rank
,
mode
.
proc_num
)),
command
=
exec_command
,
)
else
:
logger
.
warning
(
'Unknown mode %s.'
,
mode
.
name
)
return
mode_command
.
strip
()
def
__format_mode_env_value
(
self
,
value
,
proc_rank
,
proc_num
):
"""Format mode env value.
Args:
value: Env value from config.
proc_rank (int): Process rank.
proc_num (int): Process count.
Returns:
str | None: Formatted value, or None to export existing env only.
"""
if
value
is
None
:
return
None
if
isinstance
(
value
,
str
):
return
value
.
format
(
proc_rank
=
proc_rank
,
proc_num
=
proc_num
)
if
isinstance
(
value
,
(
int
,
float
,
bool
)):
return
str
(
value
)
raise
ValueError
(
f
'Unsupported env value type:
{
type
(
value
)
}
'
)
def
__format_mpi_env_args
(
self
,
env_dict
,
proc_rank
,
proc_num
):
"""Format env args for mpirun.
Args:
env_dict (DictConfig): Mode env config.
proc_rank (int): Process rank.
proc_num (int): Process count.
Returns:
list[str]: Formatted mpirun env args.
"""
env_args
=
[]
for
key
,
value
in
env_dict
.
items
():
formatted_value
=
self
.
__format_mode_env_value
(
value
,
proc_rank
,
proc_num
)
env_args
.
append
(
f
'-x
{
key
}
'
if
formatted_value
is
None
else
f
'-x
{
self
.
__quote_env_assignment
(
key
,
formatted_value
)
}
'
)
return
env_args
def
__quote_env_assignment
(
self
,
key
,
value
):
"""Quote env assignment for shell command composition.
Use double quotes so the result can be embedded inside the existing
bash -lc '...' wrapper without breaking the outer single quotes.
Args:
key (str): Env key.
value (str): Env value.
Returns:
str: Double-quoted KEY=value assignment.
"""
escaped
=
str
(
value
).
replace
(
'
\\
'
,
'
\\\\
'
).
replace
(
'"'
,
'
\\
"'
).
replace
(
'$'
,
'
\\
$'
).
replace
(
'`'
,
'
\\
`'
)
return
f
'"
{
key
}
=
{
escaped
}
"'
def
get_failure_count
(
self
):
"""Get failure count during Ansible run.
...
...
@@ -489,9 +540,13 @@ class SuperBenchRunner():
if
self
.
_docker_config
.
skip
:
env_list
=
'set -o allexport && source /tmp/sb.env && set +o allexport'
for
k
,
v
in
mode
.
env
.
items
():
if
isinstance
(
v
,
str
):
envvar
=
f
'
{
k
}
=
{
str
(
v
).
format
(
proc_rank
=
mode
.
proc_rank
,
proc_num
=
mode
.
proc_num
)
}
'
env_list
+=
f
' -e
{
envvar
}
'
if
not
self
.
_docker_config
.
skip
else
f
' && export
{
envvar
}
'
formatted_value
=
self
.
__format_mode_env_value
(
v
,
mode
.
proc_rank
,
mode
.
proc_num
)
if
formatted_value
is
not
None
:
envvar
=
self
.
__quote_env_assignment
(
k
,
formatted_value
)
env_list
+=
(
f
' -e
{
envvar
}
'
if
not
self
.
_docker_config
.
skip
else
f
' && export
{
envvar
}
'
)
fcmd
=
"docker exec {env_list} sb-workspace bash -lc '{command}'"
if
self
.
_docker_config
.
skip
:
...
...
tests/runner/test_runner.py
View file @
a10c3e15
...
...
@@ -212,6 +212,27 @@ class RunnerTestCase(unittest.TestCase):
f
'sb exec --output-dir
{
self
.
sb_output_dir
}
-c sb.config.yaml -C superbench.enable=foo'
),
},
{
'benchmark_name'
:
'foo'
,
'mode'
:
{
'name'
:
'mpi'
,
'node_num'
:
1
,
'proc_num'
:
4
,
'proc_rank'
:
1
,
'mca'
:
{},
'env'
:
{
'NCCL_BUFFSIZE'
:
4194304
,
'NCCL_RINGS'
:
'0 1 2 3|0 3 2 1'
,
'PATH'
:
None
,
},
},
'expected_command'
:
(
"mpirun -tag-output -allow-run-as-root -host localhost:4 -bind-to numa "
'-x "NCCL_BUFFSIZE=4194304" -x "NCCL_RINGS=0 1 2 3|0 3 2 1" -x PATH '
f
'sb exec --output-dir
{
self
.
sb_output_dir
}
-c sb.config.yaml -C superbench.enable=foo'
),
},
{
'benchmark_name'
:
'foo'
,
...
...
@@ -453,3 +474,34 @@ class RunnerTestCase(unittest.TestCase):
if
isinstance
(
timeout
,
int
):
timeout
=
max
(
timeout
,
60
)
self
.
assertEqual
(
timeout
,
expected_timeout
)
@
mock
.
patch
(
'superbench.runner.ansible.AnsibleClient.run'
)
def
test_run_proc_quotes_env_values
(
self
,
mock_ansible_client_run
):
"""Test _run_proc quotes env values for docker exec and mpirun."""
mock_ansible_client_run
.
return_value
=
0
self
.
runner
.
_sb_benchmarks
=
{
'foo'
:
{}}
captured
=
{}
def
fake_get_shell_config
(
cmd
):
captured
[
'cmd'
]
=
cmd
return
{
'module_args'
:
cmd
,
'cmdline'
:
''
,
'host_pattern'
:
'localhost'
,
'module'
:
'shell'
}
self
.
runner
.
_ansible_client
.
get_shell_config
=
fake_get_shell_config
mode
=
OmegaConf
.
create
({
'name'
:
'mpi'
,
'proc_num'
:
4
,
'node_num'
:
1
,
'mca'
:
{},
'env'
:
{
'NCCL_BUFFSIZE'
:
4194304
,
'NCCL_RINGS'
:
'0 1 2 3|0 3 2 1'
,
'PATH'
:
None
,
},
})
self
.
runner
.
_run_proc
(
'foo'
,
mode
,
{
'proc_rank'
:
0
})
self
.
assertIn
(
'-e "NCCL_BUFFSIZE=4194304"'
,
captured
[
'cmd'
])
self
.
assertIn
(
'-e "NCCL_RINGS=0 1 2 3|0 3 2 1"'
,
captured
[
'cmd'
])
self
.
assertIn
(
'-x "NCCL_BUFFSIZE=4194304"'
,
captured
[
'cmd'
])
self
.
assertIn
(
'-x "NCCL_RINGS=0 1 2 3|0 3 2 1"'
,
captured
[
'cmd'
])
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment