#
# SPDX-FileCopyrightText: Copyright (c) 1993-2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
from polygraphy import mod
from polygraphy.tools.args import util as args_util
from polygraphy.tools.args.base import BaseArgs
from polygraphy.tools.script import inline_identifier, inline, safe
[docs]
@mod.export()
class LoggerArgs(BaseArgs):
"""
Logging: logging and debug output
"""
def add_parser_args_impl(self):
self.group.add_argument(
"-v",
"--verbose",
help="Increase logging verbosity. Specify multiple times for higher verbosity",
action="count",
default=0,
)
self.group.add_argument(
"-q",
"--quiet",
help="Decrease logging verbosity. Specify multiple times for lower verbosity",
action="count",
default=0,
)
self.group.add_argument(
"--verbosity",
help="""
The logging verbosity to use. Takes precedence over the `-v` and `-q` options,
and unlike them, allows you to control per-path verbosity.
Verbosity values should come from Polygraphy's logging verbosities defined in
the `Logger` class and are case-insensitive.
For example: `--verbosity INFO` or `--verbosity verbose`.
To specify per-path verbosity, use the format:
`<path>:<verbosity>`. For example:
`--verbosity backend/trt:INFO backend/trt/loader.py:VERBOSE`.
Paths should be relative to the `polygraphy/` directory.
For example, `polygraphy/backend` should be specified with just `backend`.
The most closely matching path is used to determine verbosity.
For example, with: `--verbosity warning backend:info backend/trt:verbose`,
a file under `polygraphy/comparator` would use `WARNING` verbosity, one under
`backend/onnx` would use `INFO`, and one under `backend/trt` would use `VERBOSE`.
""",
nargs="+",
default=None,
)
self.group.add_argument(
"--silent", help="Disable all output", action="store_true", default=None
)
self.group.add_argument(
"--log-format",
help="Format for log messages: {{'timestamp': Include timestamp, 'line-info': Include file and line number, "
"'no-colors': Disable colors}}",
choices=["timestamp", "line-info", "no-colors"],
nargs="+",
default=[],
)
self.group.add_argument(
"--log-file",
help="Path to a file where Polygraphy logging output should be written. "
"This may not include logging output from dependencies, like TensorRT or ONNX-Runtime. ",
default=None,
)
[docs]
def parse_impl(self, args):
"""
Parses command-line arguments and populates the following attributes:
Attributes:
silent (bool): Whether to disable all logging output.
log_format (List[str]): Formatting options for the logger.
log_file (str): Path to a file where logging output should be written.
verbosity (Dict[str, str]):
Per-path logging verbosities. A key of `""` represents the default verbosity.
"""
self.silent = args_util.get(args, "silent")
self.log_format = args_util.get(args, "log_format", default=[])
self.log_file = args_util.get(args, "log_file")
severity_level = args_util.get(args, "verbose") - args_util.get(args, "quiet")
if severity_level >= 4:
default_severity = "ULTRA_VERBOSE"
elif severity_level < -4:
default_severity = "CRITICAL"
else:
default_severity = {
3: "SUPER_VERBOSE",
2: "EXTRA_VERBOSE",
1: "VERBOSE",
0: None,
-1: "START",
-2: "FINISH",
-3: "WARNING",
-4: "ERROR",
}[severity_level]
self.verbosity = None
verbosity = args_util.parse_arglist_to_dict(args_util.get(args, "verbosity"))
if default_severity is not None:
if verbosity is not None:
verbosity[""] = default_severity
else:
verbosity = {"": default_severity}
if verbosity is not None:
self.verbosity = {}
for path, sev in verbosity.items():
self.verbosity[path] = inline(
safe("G_LOGGER.{:}", inline_identifier(sev.upper()))
)
# Enable logger settings immediately on parsing.
self.get_logger()
def add_to_script_impl(self, script):
# Always required since it is used to print the exit message.
script.append_preimport(safe("from polygraphy.logger import G_LOGGER"))
logger_settings = []
if self.silent:
logger_settings.append("G_LOGGER.module_severity = G_LOGGER.CRITICAL")
elif self.verbosity is not None:
# Need to escape braces of the dictionary so it's not treated as a format-string by `safe()`.
logger_settings.append(
f"G_LOGGER.module_severity = {'{' + repr(self.verbosity) + '}'}"
)
for fmt in self.log_format:
if fmt == "no-colors":
logger_settings.append("G_LOGGER.colors = False")
elif fmt == "timestamp":
logger_settings.append("G_LOGGER.timestamp = True")
elif fmt == "line-info":
logger_settings.append("G_LOGGER.line_info = True")
if self.log_file:
logger_settings.append(f"G_LOGGER.log_file = {repr(self.log_file)}")
for setting in logger_settings:
script.append_preimport(safe(setting))
return safe("G_LOGGER")
[docs]
def get_logger(self):
"""
Gets the global logger after applying command-line options.
Returns:
G_LOGGER
"""
return args_util.run_script(self.add_to_script)