Skip to content

Commit 949f738

Browse files
Merge pull request #935 from linsword13/line-profile
Support per-line profiling for phase functions
2 parents a7bf7aa + 56aa07b commit 949f738

File tree

6 files changed

+75
-17
lines changed

6 files changed

+75
-17
lines changed

lib/ramble/ramble/application.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -120,10 +120,19 @@ def _run_phase_hook(obj, workspace, pipeline, hook):
120120

121121
hook_func_name = f"_{hook}"
122122
if hasattr(obj, hook_func_name):
123-
phase_func = getattr(obj, hook_func_name)
123+
phase_func = _get_phase_func_wrapper(workspace, getattr(obj, hook_func_name), hook)
124124
phase_func(workspace)
125125

126126

127+
def _get_phase_func_wrapper(workspace, phase_func, phase_name):
128+
if workspace.profile_config is None:
129+
return phase_func
130+
(profiler, profile_phases) = workspace.profile_config
131+
if phase_name not in profile_phases:
132+
return phase_func
133+
return profiler(phase_func)
134+
135+
127136
class ApplicationBase(metaclass=ApplicationMeta):
128137
name = None
129138
_builtin_name = NS_SEPARATOR.join(("builtin", "{name}"))
@@ -648,7 +657,7 @@ def run_phase(self, pipeline, phase, workspace):
648657

649658
for _, obj in self._objects(exclude_types=[ramble.repository.ObjectTypes.applications]):
650659
_run_phase_hook(obj, workspace, pipeline, phase)
651-
phase_func = phase_node.attribute
660+
phase_func = _get_phase_func_wrapper(workspace, phase_node.attribute, phase)
652661
phase_func(workspace, app_inst=self)
653662
self._phase_times[phase] = time.time() - start_time
654663

lib/ramble/ramble/cmd/common/arguments.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,19 @@ def include_phase_dependencies():
148148
)
149149

150150

151+
@arg
152+
def profile_phases():
153+
return Args(
154+
"--profile-phase",
155+
nargs="+",
156+
action="append",
157+
default=None,
158+
dest="profile_phases",
159+
help="phases to be profiled by line_profiler",
160+
required=False,
161+
)
162+
163+
151164
@arg
152165
def where():
153166
return Args(

lib/ramble/ramble/cmd/workspace.py

Lines changed: 42 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import sys
1111
import tempfile
1212
import argparse
13+
import itertools
1314

1415
import llnl.util.tty as tty
1516
import llnl.util.tty.color as color
@@ -443,12 +444,25 @@ def workspace_concretize(args):
443444

444445

445446
def workspace_run_pipeline(args, pipeline):
446-
include_phase_dependencies = getattr(args, "include_phase_dependencies", None)
447-
if include_phase_dependencies:
448-
with ramble.config.override("config:include_phase_dependencies", True):
447+
profile_phases = getattr(args, "profile_phases", None)
448+
if profile_phases:
449+
import line_profiler
450+
451+
profiler = line_profiler.LineProfiler()
452+
profiler.enable()
453+
p_phases = set(itertools.chain.from_iterable(profile_phases))
454+
pipeline.workspace.profile_config = (profiler, p_phases)
455+
try:
456+
include_phase_dependencies = getattr(args, "include_phase_dependencies", None)
457+
if include_phase_dependencies:
458+
with ramble.config.override("config:include_phase_dependencies", True):
459+
pipeline.run()
460+
else:
449461
pipeline.run()
450-
else:
451-
pipeline.run()
462+
finally:
463+
if profile_phases:
464+
profiler.disable()
465+
profiler.print_stats()
452466

453467

454468
def workspace_setup_setup_parser(subparser):
@@ -464,7 +478,14 @@ def workspace_setup_setup_parser(subparser):
464478

465479
arguments.add_common_arguments(
466480
subparser,
467-
["phases", "include_phase_dependencies", "where", "exclude_where", "filter_tags"],
481+
[
482+
"phases",
483+
"include_phase_dependencies",
484+
"where",
485+
"exclude_where",
486+
"filter_tags",
487+
"profile_phases",
488+
],
468489
)
469490

470491

@@ -530,7 +551,14 @@ def workspace_analyze_setup_parser(subparser):
530551

531552
arguments.add_common_arguments(
532553
subparser,
533-
["phases", "include_phase_dependencies", "where", "exclude_where", "filter_tags"],
554+
[
555+
"phases",
556+
"include_phase_dependencies",
557+
"where",
558+
"exclude_where",
559+
"filter_tags",
560+
"profile_phases",
561+
],
534562
)
535563

536564

@@ -587,7 +615,9 @@ def workspace_push_to_cache_setup_parser(subparser):
587615
"-d", dest="cache_path", default=None, required=True, help="Path to cache."
588616
)
589617

590-
arguments.add_common_arguments(subparser, ["where", "exclude_where", "filter_tags"])
618+
arguments.add_common_arguments(
619+
subparser, ["where", "exclude_where", "filter_tags", "profile_phases"]
620+
)
591621

592622

593623
def workspace_info_setup_parser(subparser):
@@ -981,7 +1011,8 @@ def workspace_archive_setup_parser(subparser):
9811011
)
9821012

9831013
arguments.add_common_arguments(
984-
subparser, ["phases", "include_phase_dependencies", "where", "exclude_where"]
1014+
subparser,
1015+
["phases", "include_phase_dependencies", "where", "exclude_where", "profile_phases"],
9851016
)
9861017

9871018

@@ -1024,7 +1055,8 @@ def workspace_mirror_setup_parser(subparser):
10241055
)
10251056

10261057
arguments.add_common_arguments(
1027-
subparser, ["phases", "include_phase_dependencies", "where", "exclude_where"]
1058+
subparser,
1059+
["phases", "include_phase_dependencies", "where", "exclude_where", "profile_phases"],
10281060
)
10291061

10301062

lib/ramble/ramble/workspace/workspace.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -487,6 +487,9 @@ def __init__(self, root, dry_run=False, read_default_template=True):
487487

488488
self.deployment_name = self.name
489489

490+
# Used by profiling phases
491+
self.profile_config = None
492+
490493
def _re_read(self):
491494
"""Reinitialize the workspace object if it has been written (this
492495
may not be true if the workspace was just created in this running

requirements-dev.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,4 @@ coverage
66
pre-commit
77
pytest-xdist
88
pytest-cov
9+
line_profiler

share/ramble/ramble-completion.bash

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -646,7 +646,7 @@ _ramble_workspace_activate() {
646646
}
647647

648648
_ramble_workspace_archive() {
649-
RAMBLE_COMPREPLY="-h --help --tar-archive -t --prefix -p --upload-url -u --include-secrets --phases --include-phase-dependencies --where --exclude-where"
649+
RAMBLE_COMPREPLY="-h --help --tar-archive -t --prefix -p --upload-url -u --include-secrets --phases --include-phase-dependencies --where --exclude-where --profile-phase"
650650
}
651651

652652
_ramble_workspace_deactivate() {
@@ -667,15 +667,15 @@ _ramble_workspace_concretize() {
667667
}
668668

669669
_ramble_workspace_setup() {
670-
RAMBLE_COMPREPLY="-h --help --dry-run --phases --include-phase-dependencies --where --exclude-where --filter-tags"
670+
RAMBLE_COMPREPLY="-h --help --dry-run --phases --include-phase-dependencies --where --exclude-where --filter-tags --profile-phase"
671671
}
672672

673673
_ramble_workspace_analyze() {
674-
RAMBLE_COMPREPLY="-h --help -f --formats -u --upload -p --print-results -s --summary-only --phases --include-phase-dependencies --where --exclude-where --filter-tags"
674+
RAMBLE_COMPREPLY="-h --help -f --formats -u --upload -p --print-results -s --summary-only --phases --include-phase-dependencies --where --exclude-where --filter-tags --profile-phase"
675675
}
676676

677677
_ramble_workspace_push_to_cache() {
678-
RAMBLE_COMPREPLY="-h --help -d --where --exclude-where --filter-tags"
678+
RAMBLE_COMPREPLY="-h --help -d --where --exclude-where --filter-tags --profile-phase"
679679
}
680680

681681
_ramble_workspace_info() {
@@ -692,7 +692,7 @@ _ramble_workspace_edit() {
692692
}
693693

694694
_ramble_workspace_mirror() {
695-
RAMBLE_COMPREPLY="-h --help -d --dry-run --phases --include-phase-dependencies --where --exclude-where"
695+
RAMBLE_COMPREPLY="-h --help -d --dry-run --phases --include-phase-dependencies --where --exclude-where --profile-phase"
696696
}
697697

698698
_ramble_workspace_experiment_logs() {

0 commit comments

Comments
 (0)