Python updates (#38)

* silence SFINAE disabled for fork_gotcha

* Python updates

- Options for --{module,function}-include
- libpyomnitrace is_initialized and is_finalized
- source instrumentation auto init
- atexit finalization
- improved python testing

* Documentation Update

* Fix to 'cmake -E cat' not available < cmake v3.18

* Fix for inverse tests

* Update cancelling.yml

[ROCm/rocprofiler-systems commit: 593b3b69b8]
This commit is contained in:
Jonathan R. Madsen
2022-04-05 20:40:27 -05:00
committed by GitHub
vanhempi 6daac0f60c
commit e7546b201a
21 muutettua tiedostoa jossa 916 lisäystä ja 237 poistoa
@@ -43,6 +43,8 @@ try:
)
from .libpyomnitrace import initialize
from .libpyomnitrace import finalize
from .libpyomnitrace import is_initialized
from .libpyomnitrace import is_finalized
from .libpyomnitrace.profiler import config as Config
config = Config
@@ -52,6 +54,8 @@ try:
__all__ = [
"initialize",
"finalize",
"is_initialized",
"is_finalized",
"Profiler",
"Config",
"FakeProfiler",
@@ -63,5 +67,13 @@ try:
"noprofile",
]
import atexit
def _finalize_at_exit():
if not is_finalized():
finalize()
atexit.register(_finalize_at_exit)
except Exception as e:
print("{}".format(e))
@@ -93,33 +93,42 @@ def parse_args(args=None):
else:
raise argparse.ArgumentTypeError("Boolean value expected.")
parser = argparse.ArgumentParser(add_help=True)
parser.add_argument(
"-c",
"--config",
default=None,
type=str,
help="Omnitrace configuration file",
parser = argparse.ArgumentParser(
"omnitrace",
add_help=True,
epilog="usage: {} -m omnitrace <OMNITRACE_ARGS> -- <SCRIPT> <SCRIPT_ARGS>".format(
os.path.basename(sys.executable)
),
)
parser.add_argument(
"-b",
"--builtin",
action="store_true",
help="Put 'profile' in the builtins. Use 'profile.enable()' and "
"'profile.disable()' in your code to turn it on and off, or "
"'@profile' to decorate a single function, or 'with profile:' "
"to profile a single section of code.",
help=(
"Put 'profile' in the builtins. Use '@profile' to decorate a single function, "
"or 'with profile:' to profile a single section of code."
),
)
parser.add_argument(
"-c",
"--config",
default=None,
type=str,
metavar="FILE",
help="Omnitrace configuration file",
)
parser.add_argument(
"-s",
"--setup",
default=None,
metavar="FILE",
help="Code to execute before the code to profile",
)
parser.add_argument(
"--trace-c",
type=str2bool,
nargs="?",
metavar="BOOL",
const=True,
default=_profiler_config.trace_c,
help="Enable profiling C functions",
@@ -129,6 +138,7 @@ def parse_args(args=None):
"--include-args",
type=str2bool,
nargs="?",
metavar="BOOL",
const=True,
default=_profiler_config.include_args,
help="Encode the argument values",
@@ -138,6 +148,7 @@ def parse_args(args=None):
"--include-line",
type=str2bool,
nargs="?",
metavar="BOOL",
const=True,
default=_profiler_config.include_line,
help="Encode the function line number",
@@ -147,6 +158,7 @@ def parse_args(args=None):
"--include-file",
type=str2bool,
nargs="?",
metavar="BOOL",
const=True,
default=_profiler_config.include_filename,
help="Encode the function filename",
@@ -156,36 +168,63 @@ def parse_args(args=None):
"--full-filepath",
type=str2bool,
nargs="?",
metavar="BOOL",
const=True,
default=_profiler_config.full_filepath,
help="Encode the full function filename (instead of basename)",
)
parser.add_argument(
"--skip-funcs",
"-I",
"--function-include",
type=str,
nargs="+",
default=_profiler_config.skip_functions,
metavar="FUNC",
default=_profiler_config.include_functions,
help="Include any entries with these function names",
)
parser.add_argument(
"-E",
"--function-exclude",
type=str,
nargs="+",
metavar="FUNC",
default=_profiler_config.exclude_functions,
help="Filter out any entries with these function names",
)
parser.add_argument(
"--skip-files",
"-R",
"--function-restrict",
type=str,
nargs="+",
default=_profiler_config.skip_filenames,
help="Filter out any entries from these files",
)
parser.add_argument(
"--only-funcs",
type=str,
nargs="+",
default=_profiler_config.only_functions,
metavar="FUNC",
default=_profiler_config.restrict_functions,
help="Select only entries with these function names",
)
parser.add_argument(
"--only-files",
"-MI",
"--module-include",
type=str,
nargs="+",
default=_profiler_config.only_filenames,
metavar="FILE",
default=_profiler_config.include_modules,
help="Include any entries from these files",
)
parser.add_argument(
"-ME",
"--module-exclude",
type=str,
nargs="+",
metavar="FILE",
default=_profiler_config.exclude_modules,
help="Filter out any entries from these files",
)
parser.add_argument(
"-MR",
"--module-restrict",
type=str,
nargs="+",
metavar="FILE",
default=_profiler_config.restrict_modules,
help="Select only entries from these files",
)
parser.add_argument(
@@ -282,7 +321,7 @@ def main():
if os.path.isfile(argv[0]):
argv[0] = os.path.realpath(argv[0])
initialize(argv[0])
initialize(argv)
from .libpyomnitrace.profiler import config as _profiler_config
@@ -291,10 +330,12 @@ def main():
_profiler_config.include_line = opts.include_line
_profiler_config.include_filename = opts.include_file
_profiler_config.full_filepath = opts.full_filepath
_profiler_config.skip_functions = opts.skip_funcs
_profiler_config.skip_filenames = opts.skip_files
_profiler_config.only_functions = opts.only_funcs
_profiler_config.only_filenames = opts.only_files
_profiler_config.include_functions = opts.function_include
_profiler_config.include_modules = opts.module_include
_profiler_config.exclude_functions = opts.function_exclude
_profiler_config.exclude_modules = opts.module_exclude
_profiler_config.restrict_functions = opts.function_restrict
_profiler_config.restrict_modules = opts.module_restrict
_profiler_config.verbosity = opts.verbosity
print("[omnitrace]> profiling: {}".format(argv))
@@ -30,6 +30,7 @@ __version__ = "@PROJECT_VERSION@"
__maintainer__ = "AMD Research"
__status__ = "Development"
import os
import sys
import threading
from functools import wraps
@@ -80,6 +81,68 @@ config = _profiler_config
Config = _profiler_config
def _file(back=2, only_basename=True, use_dirname=False, noquotes=True):
"""
Returns the file name
"""
from os.path import basename, dirname
def get_fcode(back):
fname = "<module>"
try:
fname = sys._getframe(back).f_code.co_filename
except Exception as e:
print(e)
fname = "<module>"
return fname
result = None
if only_basename is True:
if use_dirname is True:
result = "{}".format(
join(
basename(dirname(get_fcode(back))),
basename(get_fcode(back)),
)
)
else:
result = "{}".format(basename(get_fcode(back)))
else:
result = "{}".format(get_fcode(back))
if noquotes is False:
result = "'{}'".format(result)
return result
def _get_argv(init_file, argv=None):
if argv is None:
argv = sys.argv[:]
if "--" in argv:
_idx = argv.index("--")
argv = sys.argv[(_idx + 1) :]
if len(argv) > 1:
if argv[0] == "-m":
argv = argv[1:]
elif argv[0] == "-c":
argv[0] = os.path.basename(sys.executable)
else:
while len(argv) > 1 and argv[0].startswith("-"):
argv = argv[1:]
if os.path.exists(argv[0]):
break
if len(argv) == 0:
argv = [init_file]
elif not os.path.exists(argv[0]):
argv[0] = init_file
return argv
#
class Profiler:
"""Provides decorators and context-manager for the omnitrace profilers"""
@@ -118,8 +181,11 @@ class Profiler:
)
self._unset = 0
self._use = (
not _profiler_config._is_running and Profiler.is_enabled() is True
not _profiler_config._is_running
and Profiler.is_enabled() is True
and not libpyomnitrace.is_finalized()
)
self._file = _file()
self.debug = kwargs["debug"] if "debug" in kwargs else False
# ---------------------------------------------------------------------------------- #
@@ -135,6 +201,9 @@ class Profiler:
def configure(self):
"""Initialize, configure the bundle, store original profiler function"""
if not libpyomnitrace.is_initialized():
libpyomnitrace.initialize(_get_argv(self._file))
_profiler_init()
# store original
@@ -157,6 +226,7 @@ class Profiler:
not _profiler_config._is_running
and Profiler.is_enabled() is True
and sys.getprofile() == self._original_function
and not libpyomnitrace.is_finalized()
)
# ---------------------------------------------------------------------------------- #