# Path: sacred/utils.py
# @wrapt.decorator
# def optional_kwargs_decorator(wrapped, instance=None, args=None, kwargs=None):
#     # here wrapped is itself a decorator
#     if args:  # means it was used as a normal decorator (so just call it)
#         return wrapped(*args, **kwargs)
#     else:  # used with kwargs, so we need to return a decorator
#         return partial(wrapped, **kwargs)
# 
# Path: sacred/settings.py
# SETTINGS = FrozenKeyMunch.fromDict(
#     {
#         "CONFIG": {
#             # make sure all config keys are compatible with MongoDB
#             "ENFORCE_KEYS_MONGO_COMPATIBLE": True,
#             # make sure all config keys are serializable with jsonpickle
#             # THIS IS IMPORTANT. Only deactivate if you know what you're doing.
#             "ENFORCE_KEYS_JSONPICKLE_COMPATIBLE": True,
#             # make sure all config keys are valid python identifiers
#             "ENFORCE_VALID_PYTHON_IDENTIFIER_KEYS": False,
#             # make sure all config keys are strings
#             "ENFORCE_STRING_KEYS": False,
#             # make sure no config key contains an equals sign
#             "ENFORCE_KEYS_NO_EQUALS": True,
#             # if true, all dicts and lists in the configuration of a captured
#             # function are replaced with a read-only container that raises an
#             # Exception if it is attempted to write to those containers
#             "READ_ONLY_CONFIG": True,
#             # regex patterns to filter out certain IDE or linter directives
#             # from inline comments in the documentation
#             "IGNORED_COMMENTS": ["^pylint:", "^noinspection"],
#             # if true uses the numpy legacy API, i.e. _rnd in captured functions is
#             # a numpy.random.RandomState rather than numpy.random.Generator.
#             # numpy.random.RandomState became legacy with numpy v1.19.
#             "NUMPY_RANDOM_LEGACY_API": version.parse(opt.np.__version__)
#             < version.parse("1.19")
#             if opt.has_numpy
#             else False,
#         },
#         "HOST_INFO": {
#             # Collect information about GPUs using the nvidia-smi tool
#             "INCLUDE_GPU_INFO": True,
#             # List of ENVIRONMENT variables to store in host-info
#             "CAPTURED_ENV": [],
#         },
#         "COMMAND_LINE": {
#             # disallow string fallback, if parsing a value from command-line
#             # failed
#             "STRICT_PARSING": False,
#             # show command line options that are disabled (e.g. unmet
#             # dependencies)
#             "SHOW_DISABLED_OPTIONS": True,
#         },
#         # configure how stdout/stderr are captured. ['no', 'sys', 'fd']
#         "CAPTURE_MODE": "sys" if platform.system() == "Windows" else "fd",
#         # configure how dependencies are discovered. [none, imported, sys, pkg]
#         "DISCOVER_DEPENDENCIES": "imported",
#         # configure how source-files are discovered. [none, imported, sys, dir]
#         "DISCOVER_SOURCES": "imported",
#     },
# )


import os
import platform
import re
import subprocess
import warnings
import cpuinfo
from xml.etree import ElementTree
from typing import List
from sacred.utils import optional_kwargs_decorator
from sacred.settings import SETTINGS
    try:
        xml = subprocess.check_output(["nvidia-smi", "-q", "-x"]).decode(
            "utf-8", "replace"
        )
    except (FileNotFoundError, OSError, subprocess.CalledProcessError):
        raise IgnoreHostInfo()

    gpu_info = {"gpus": []}
    for child in ElementTree.fromstring(xml):
        if child.tag == "driver_version":
            gpu_info["driver_version"] = child.text
        if child.tag != "gpu":
            continue
        fb_memory_usage = child.find("fb_memory_usage").find("total").text
        if fb_memory_usage == "Insufficient Permissions":
            # for Multi-Instance GPU (MIG) instances
            mig = child.find("mig_devices").find("mig_device")
            fb_memory_usage = mig.find("fb_memory_usage").find("total").text
        gpu = {
            "model": child.find("product_name").text,
            "total_memory": int(fb_memory_usage.split()[0]),
            "persistence_mode": (child.find("persistence_mode").text == "Enabled"),
        }
        gpu_info["gpus"].append(gpu)

    return gpu_info


@host_info_gatherer(name="ENV")
def _environment():

# Path: sacred/utils.py
# @wrapt.decorator
# def optional_kwargs_decorator(wrapped, instance=None, args=None, kwargs=None):
#     # here wrapped is itself a decorator
#     if args:  # means it was used as a normal decorator (so just call it)
#         return wrapped(*args, **kwargs)
#     else:  # used with kwargs, so we need to return a decorator
#         return partial(wrapped, **kwargs)
# 
# Path: sacred/settings.py
# SETTINGS = FrozenKeyMunch.fromDict(
#     {
#         "CONFIG": {
#             # make sure all config keys are compatible with MongoDB
#             "ENFORCE_KEYS_MONGO_COMPATIBLE": True,
#             # make sure all config keys are serializable with jsonpickle
#             # THIS IS IMPORTANT. Only deactivate if you know what you're doing.
#             "ENFORCE_KEYS_JSONPICKLE_COMPATIBLE": True,
#             # make sure all config keys are valid python identifiers
#             "ENFORCE_VALID_PYTHON_IDENTIFIER_KEYS": False,
#             # make sure all config keys are strings
#             "ENFORCE_STRING_KEYS": False,
#             # make sure no config key contains an equals sign
#             "ENFORCE_KEYS_NO_EQUALS": True,
#             # if true, all dicts and lists in the configuration of a captured
#             # function are replaced with a read-only container that raises an
#             # Exception if it is attempted to write to those containers
#             "READ_ONLY_CONFIG": True,
#             # regex patterns to filter out certain IDE or linter directives
#             # from inline comments in the documentation
#             "IGNORED_COMMENTS": ["^pylint:", "^noinspection"],
#             # if true uses the numpy legacy API, i.e. _rnd in captured functions is
#             # a numpy.random.RandomState rather than numpy.random.Generator.
#             # numpy.random.RandomState became legacy with numpy v1.19.
#             "NUMPY_RANDOM_LEGACY_API": version.parse(opt.np.__version__)
#             < version.parse("1.19")
#             if opt.has_numpy
#             else False,
#         },
#         "HOST_INFO": {
#             # Collect information about GPUs using the nvidia-smi tool
#             "INCLUDE_GPU_INFO": True,
#             # List of ENVIRONMENT variables to store in host-info
#             "CAPTURED_ENV": [],
#         },
#         "COMMAND_LINE": {
#             # disallow string fallback, if parsing a value from command-line
#             # failed
#             "STRICT_PARSING": False,
#             # show command line options that are disabled (e.g. unmet
#             # dependencies)
#             "SHOW_DISABLED_OPTIONS": True,
#         },
#         # configure how stdout/stderr are captured. ['no', 'sys', 'fd']
#         "CAPTURE_MODE": "sys" if platform.system() == "Windows" else "fd",
#         # configure how dependencies are discovered. [none, imported, sys, pkg]
#         "DISCOVER_DEPENDENCIES": "imported",
#         # configure how source-files are discovered. [none, imported, sys, dir]
#         "DISCOVER_SOURCES": "imported",
#     },
# )


# Path: sacred/host_info.py
import os
import platform
import re
import subprocess
import warnings
import cpuinfo
from xml.etree import ElementTree
from typing import List
from sacred.utils import optional_kwargs_decorator
from sacred.settings import SETTINGS

    try:
        xml = subprocess.check_output(["nvidia-smi", "-q", "-x"]).decode(
            "utf-8", "replace"
        )
    except (FileNotFoundError, OSError, subprocess.CalledProcessError):
        raise IgnoreHostInfo()

    gpu_info = {"gpus": []}
    for child in ElementTree.fromstring(xml):
        if child.tag == "driver_version":
            gpu_info["driver_version"] = child.text
        if child.tag != "gpu":
            continue
        fb_memory_usage = child.find("fb_memory_usage").find("total").text
        if fb_memory_usage == "Insufficient Permissions":
            # for Multi-Instance GPU (MIG) instances
            mig = child.find("mig_devices").find("mig_device")
            fb_memory_usage = mig.find("fb_memory_usage").find("total").text
        gpu = {
            "model": child.find("product_name").text,
            "total_memory": int(fb_memory_usage.split()[0]),
            "persistence_mode": (child.find("persistence_mode").text == "Enabled"),
        }
        gpu_info["gpus"].append(gpu)

    return gpu_info


@host_info_gatherer(name="ENV")
def _environment():

    keys_to_capture = SETTINGS.HOST_INFO.CAPTURED_ENV