ai-content-maker/.venv/Lib/site-packages/numba/misc/numba_sysinfo.py

690 lines
26 KiB
Python

import json
import locale
import multiprocessing
import os
import platform
import textwrap
import sys
from contextlib import redirect_stdout
from datetime import datetime
from io import StringIO
from subprocess import check_output, PIPE, CalledProcessError
import numpy as np
import llvmlite.binding as llvmbind
from llvmlite import __version__ as llvmlite_version
from numba import cuda as cu, __version__ as version_number
from numba.cuda import cudadrv
from numba.cuda.cudadrv.driver import driver as cudriver
from numba.cuda.cudadrv.runtime import runtime as curuntime
from numba.core import config
_psutil_import = False
try:
import psutil
except ImportError:
pass
else:
_psutil_import = True
__all__ = ['get_sysinfo', 'display_sysinfo']
# Keys of a `sysinfo` dictionary
# Time info
_start, _start_utc, _runtime = 'Start', 'Start UTC', 'Runtime'
_numba_version = 'Numba Version'
# Hardware info
_machine = 'Machine'
_cpu_name, _cpu_count = 'CPU Name', 'CPU Count'
_cpus_allowed, _cpus_list = 'CPUs Allowed', 'List CPUs Allowed'
_cpu_features = 'CPU Features'
_cfs_quota, _cfs_period = 'CFS Quota', 'CFS Period',
_cfs_restrict = 'CFS Restriction'
_mem_total, _mem_available = 'Mem Total', 'Mem Available'
# OS info
_platform_name, _platform_release = 'Platform Name', 'Platform Release'
_os_name, _os_version = 'OS Name', 'OS Version'
_os_spec_version = 'OS Specific Version'
_libc_version = 'Libc Version'
# Python info
_python_comp = 'Python Compiler'
_python_impl = 'Python Implementation'
_python_version = 'Python Version'
_python_locale = 'Python Locale'
# LLVM info
_llvmlite_version = 'llvmlite Version'
_llvm_version = 'LLVM Version'
# CUDA info
_cu_dev_init = 'CUDA Device Init'
_cu_drv_ver = 'CUDA Driver Version'
_cu_rt_ver = 'CUDA Runtime Version'
_cu_nvidia_bindings = 'NVIDIA CUDA Bindings'
_cu_nvidia_bindings_used = 'NVIDIA CUDA Bindings In Use'
_cu_detect_out, _cu_lib_test = 'CUDA Detect Output', 'CUDA Lib Test'
_cu_mvc_available = 'NVIDIA CUDA Minor Version Compatibility Available'
_cu_mvc_needed = 'NVIDIA CUDA Minor Version Compatibility Needed'
_cu_mvc_in_use = 'NVIDIA CUDA Minor Version Compatibility In Use'
# NumPy info
_numpy_version = 'NumPy Version'
_numpy_supported_simd_features = 'NumPy Supported SIMD features'
_numpy_supported_simd_dispatch = 'NumPy Supported SIMD dispatch'
_numpy_supported_simd_baseline = 'NumPy Supported SIMD baseline'
_numpy_AVX512_SKX_detected = 'NumPy AVX512_SKX detected'
# SVML info
_svml_state, _svml_loaded = 'SVML State', 'SVML Lib Loaded'
_llvm_svml_patched = 'LLVM SVML Patched'
_svml_operational = 'SVML Operational'
# Threading layer info
_tbb_thread, _tbb_error = 'TBB Threading', 'TBB Threading Error'
_openmp_thread, _openmp_error = 'OpenMP Threading', 'OpenMP Threading Error'
_openmp_vendor = 'OpenMP vendor'
_wkq_thread, _wkq_error = 'Workqueue Threading', 'Workqueue Threading Error'
# Numba info
_numba_env_vars = 'Numba Env Vars'
# Conda info
_conda_build_ver, _conda_env_ver = 'Conda Build', 'Conda Env'
_conda_platform, _conda_python_ver = 'Conda Platform', 'Conda Python Version'
_conda_root_writable = 'Conda Root Writable'
# Packages info
_inst_pkg = 'Installed Packages'
# Psutil info
_psutil = 'Psutil Available'
# Errors and warnings
_errors = 'Errors'
_warnings = 'Warnings'
# Error and warning log
_error_log = []
_warning_log = []
def get_os_spec_info(os_name):
# Linux man page for `/proc`:
# http://man7.org/linux/man-pages/man5/proc.5.html
# Windows documentation for `wmic OS`:
# https://docs.microsoft.com/en-us/windows/win32/cimwin32prov/cim-operatingsystem
# MacOS man page for `sysctl`:
# https://www.unix.com/man-page/osx/3/sysctl/
# MacOS man page for `vm_stat`:
# https://www.unix.com/man-page/osx/1/vm_stat/
class CmdBufferOut(tuple):
buffer_output_flag = True
class CmdReadFile(tuple):
read_file_flag = True
shell_params = {
'Linux': {
'cmd': (
CmdReadFile(('/sys/fs/cgroup/cpuacct/cpu.cfs_quota_us',)),
CmdReadFile(('/sys/fs/cgroup/cpuacct/cpu.cfs_period_us',)),
),
'cmd_optional': (
CmdReadFile(('/proc/meminfo',)),
CmdReadFile(('/proc/self/status',)),
),
'kwds': {
# output string fragment -> result dict key
'MemTotal:': _mem_total,
'MemAvailable:': _mem_available,
'Cpus_allowed:': _cpus_allowed,
'Cpus_allowed_list:': _cpus_list,
'/sys/fs/cgroup/cpuacct/cpu.cfs_quota_us': _cfs_quota,
'/sys/fs/cgroup/cpuacct/cpu.cfs_period_us': _cfs_period,
},
},
'Windows': {
'cmd': (),
'cmd_optional': (
CmdBufferOut(('wmic', 'OS', 'get', 'TotalVirtualMemorySize')),
CmdBufferOut(('wmic', 'OS', 'get', 'FreeVirtualMemory')),
),
'kwds': {
# output string fragment -> result dict key
'TotalVirtualMemorySize': _mem_total,
'FreeVirtualMemory': _mem_available,
},
},
'Darwin': {
'cmd': (),
'cmd_optional': (
('sysctl', 'hw.memsize'),
('vm_stat'),
),
'kwds': {
# output string fragment -> result dict key
'hw.memsize:': _mem_total,
'free:': _mem_available,
},
'units': {
_mem_total: 1, # Size is given in bytes.
_mem_available: 4096, # Size is given in 4kB pages.
},
},
}
os_spec_info = {}
params = shell_params.get(os_name, {})
cmd_selected = params.get('cmd', ())
if _psutil_import:
vm = psutil.virtual_memory()
os_spec_info.update({
_mem_total: vm.total,
_mem_available: vm.available,
})
p = psutil.Process()
cpus_allowed = p.cpu_affinity() if hasattr(p, 'cpu_affinity') else []
if cpus_allowed:
os_spec_info[_cpus_allowed] = len(cpus_allowed)
os_spec_info[_cpus_list] = ' '.join(str(n) for n in cpus_allowed)
else:
_warning_log.append(
"Warning (psutil): psutil cannot be imported. "
"For more accuracy, consider installing it.")
# Fallback to internal heuristics
cmd_selected += params.get('cmd_optional', ())
# Assuming the shell cmd returns a unique (k, v) pair per line
# or a unique (k, v) pair spread over several lines:
# Gather output in a list of strings containing a keyword and some value.
output = []
for cmd in cmd_selected:
if hasattr(cmd, 'read_file_flag'):
# Open file within Python
if os.path.exists(cmd[0]):
try:
with open(cmd[0], 'r') as f:
out = f.readlines()
if out:
out[0] = ' '.join((cmd[0], out[0]))
output.extend(out)
except OSError as e:
_error_log.append(f'Error (file read): {e}')
continue
else:
_warning_log.append('Warning (no file): {}'.format(cmd[0]))
continue
else:
# Spawn a subprocess
try:
out = check_output(cmd, stderr=PIPE)
except (OSError, CalledProcessError) as e:
_error_log.append(f'Error (subprocess): {e}')
continue
if hasattr(cmd, 'buffer_output_flag'):
out = b' '.join(line for line in out.splitlines()) + b'\n'
output.extend(out.decode().splitlines())
# Extract (k, output) pairs by searching for keywords in output
kwds = params.get('kwds', {})
for line in output:
match = kwds.keys() & line.split()
if match and len(match) == 1:
k = kwds[match.pop()]
os_spec_info[k] = line
elif len(match) > 1:
print(f'Ambiguous output: {line}')
# Try to extract something meaningful from output string
def format():
# CFS restrictions
split = os_spec_info.get(_cfs_quota, '').split()
if split:
os_spec_info[_cfs_quota] = float(split[-1])
split = os_spec_info.get(_cfs_period, '').split()
if split:
os_spec_info[_cfs_period] = float(split[-1])
if os_spec_info.get(_cfs_quota, -1) != -1:
cfs_quota = os_spec_info.get(_cfs_quota, '')
cfs_period = os_spec_info.get(_cfs_period, '')
runtime_amount = cfs_quota / cfs_period
os_spec_info[_cfs_restrict] = runtime_amount
def format_optional():
# Memory
units = {_mem_total: 1024, _mem_available: 1024}
units.update(params.get('units', {}))
for k in (_mem_total, _mem_available):
digits = ''.join(d for d in os_spec_info.get(k, '') if d.isdigit())
os_spec_info[k] = int(digits or 0) * units[k]
# Accessible CPUs
split = os_spec_info.get(_cpus_allowed, '').split()
if split:
n = split[-1]
n = n.split(',')[-1]
os_spec_info[_cpus_allowed] = str(bin(int(n or 0, 16))).count('1')
split = os_spec_info.get(_cpus_list, '').split()
if split:
os_spec_info[_cpus_list] = split[-1]
try:
format()
if not _psutil_import:
format_optional()
except Exception as e:
_error_log.append(f'Error (format shell output): {e}')
# Call OS specific functions
os_specific_funcs = {
'Linux': {
_libc_version: lambda: ' '.join(platform.libc_ver())
},
'Windows': {
_os_spec_version: lambda: ' '.join(
s for s in platform.win32_ver()),
},
'Darwin': {
_os_spec_version: lambda: ''.join(
i or ' ' for s in tuple(platform.mac_ver()) for i in s),
},
}
key_func = os_specific_funcs.get(os_name, {})
os_spec_info.update({k: f() for k, f in key_func.items()})
return os_spec_info
def get_sysinfo():
# Gather the information that shouldn't raise exceptions
sys_info = {
_start: datetime.now(),
_start_utc: datetime.utcnow(),
_machine: platform.machine(),
_cpu_name: llvmbind.get_host_cpu_name(),
_cpu_count: multiprocessing.cpu_count(),
_platform_name: platform.platform(aliased=True),
_platform_release: platform.release(),
_os_name: platform.system(),
_os_version: platform.version(),
_python_comp: platform.python_compiler(),
_python_impl: platform.python_implementation(),
_python_version: platform.python_version(),
_numba_env_vars: {k: v for (k, v) in os.environ.items()
if k.startswith('NUMBA_')},
_numba_version: version_number,
_llvm_version: '.'.join(str(i) for i in llvmbind.llvm_version_info),
_llvmlite_version: llvmlite_version,
_psutil: _psutil_import,
}
# CPU features
try:
feature_map = llvmbind.get_host_cpu_features()
except RuntimeError as e:
_error_log.append(f'Error (CPU features): {e}')
else:
features = sorted([key for key, value in feature_map.items() if value])
sys_info[_cpu_features] = ' '.join(features)
# Python locale
# On MacOSX, getdefaultlocale can raise. Check again if Py > 3.7.5
try:
# If $LANG is unset, getdefaultlocale() can return (None, None), make
# sure we can encode this as strings by casting explicitly.
sys_info[_python_locale] = '.'.join([str(i) for i in
locale.getdefaultlocale()])
except Exception as e:
_error_log.append(f'Error (locale): {e}')
# CUDA information
try:
cu.list_devices()[0] # will a device initialise?
except Exception as e:
sys_info[_cu_dev_init] = False
msg_not_found = "CUDA driver library cannot be found"
msg_disabled_by_user = "CUDA is disabled"
msg_end = " or no CUDA enabled devices are present."
msg_generic_problem = "CUDA device initialisation problem."
msg = getattr(e, 'msg', None)
if msg is not None:
if msg_not_found in msg:
err_msg = msg_not_found + msg_end
elif msg_disabled_by_user in msg:
err_msg = msg_disabled_by_user + msg_end
else:
err_msg = msg_generic_problem + " Message:" + msg
else:
err_msg = msg_generic_problem + " " + str(e)
# Best effort error report
_warning_log.append("Warning (cuda): %s\nException class: %s" %
(err_msg, str(type(e))))
else:
try:
sys_info[_cu_dev_init] = True
output = StringIO()
with redirect_stdout(output):
cu.detect()
sys_info[_cu_detect_out] = output.getvalue()
output.close()
cu_drv_ver = cudriver.get_version()
cu_rt_ver = curuntime.get_version()
sys_info[_cu_drv_ver] = '%s.%s' % cu_drv_ver
sys_info[_cu_rt_ver] = '%s.%s' % cu_rt_ver
output = StringIO()
with redirect_stdout(output):
cudadrv.libs.test()
sys_info[_cu_lib_test] = output.getvalue()
output.close()
try:
from cuda import cuda # noqa: F401
nvidia_bindings_available = True
except ImportError:
nvidia_bindings_available = False
sys_info[_cu_nvidia_bindings] = nvidia_bindings_available
nv_binding_used = bool(cudadrv.driver.USE_NV_BINDING)
sys_info[_cu_nvidia_bindings_used] = nv_binding_used
try:
from ptxcompiler import compile_ptx # noqa: F401
from cubinlinker import CubinLinker # noqa: F401
sys_info[_cu_mvc_available] = True
except ImportError:
sys_info[_cu_mvc_available] = False
sys_info[_cu_mvc_needed] = cu_rt_ver > cu_drv_ver
sys_info[_cu_mvc_in_use] = bool(
config.CUDA_ENABLE_MINOR_VERSION_COMPATIBILITY)
except Exception as e:
_warning_log.append(
"Warning (cuda): Probing CUDA failed "
"(device and driver present, runtime problem?)\n"
f"(cuda) {type(e)}: {e}")
# NumPy information
sys_info[_numpy_version] = np.version.full_version
try:
# NOTE: These consts were added in NumPy 1.20
from numpy.core._multiarray_umath import (__cpu_features__,
__cpu_dispatch__,
__cpu_baseline__,)
except ImportError:
sys_info[_numpy_AVX512_SKX_detected] = False
else:
feat_filtered = [k for k, v in __cpu_features__.items() if v]
sys_info[_numpy_supported_simd_features] = feat_filtered
sys_info[_numpy_supported_simd_dispatch] = __cpu_dispatch__
sys_info[_numpy_supported_simd_baseline] = __cpu_baseline__
sys_info[_numpy_AVX512_SKX_detected] = \
__cpu_features__.get("AVX512_SKX", False)
# SVML information
# Replicate some SVML detection logic from numba.__init__ here.
# If SVML load fails in numba.__init__ the splitting of the logic
# here will help diagnosing the underlying issue.
svml_lib_loaded = True
try:
if sys.platform.startswith('linux'):
llvmbind.load_library_permanently("libsvml.so")
elif sys.platform.startswith('darwin'):
llvmbind.load_library_permanently("libsvml.dylib")
elif sys.platform.startswith('win'):
llvmbind.load_library_permanently("svml_dispmd")
else:
svml_lib_loaded = False
except Exception:
svml_lib_loaded = False
func = getattr(llvmbind.targets, "has_svml", None)
sys_info[_llvm_svml_patched] = func() if func else False
sys_info[_svml_state] = config.USING_SVML
sys_info[_svml_loaded] = svml_lib_loaded
sys_info[_svml_operational] = all((
sys_info[_svml_state],
sys_info[_svml_loaded],
sys_info[_llvm_svml_patched],
))
# Check which threading backends are available.
def parse_error(e, backend):
# parses a linux based error message, this is to provide feedback
# and hide user paths etc
try:
path, problem, symbol = [x.strip() for x in e.msg.split(':')]
extn_dso = os.path.split(path)[1]
if backend in extn_dso:
return "%s: %s" % (problem, symbol)
except Exception:
pass
return "Unknown import problem."
try:
# check import is ok, this means the DSO linkage is working
from numba.np.ufunc import tbbpool # NOQA
# check that the version is compatible, this is a check performed at
# runtime (well, compile time), it will also ImportError if there's
# a problem.
from numba.np.ufunc.parallel import _check_tbb_version_compatible
_check_tbb_version_compatible()
sys_info[_tbb_thread] = True
except ImportError as e:
# might be a missing symbol due to e.g. tbb libraries missing
sys_info[_tbb_thread] = False
sys_info[_tbb_error] = parse_error(e, 'tbbpool')
try:
from numba.np.ufunc import omppool
sys_info[_openmp_thread] = True
sys_info[_openmp_vendor] = omppool.openmp_vendor
except ImportError as e:
sys_info[_openmp_thread] = False
sys_info[_openmp_error] = parse_error(e, 'omppool')
try:
from numba.np.ufunc import workqueue # NOQA
sys_info[_wkq_thread] = True
except ImportError as e:
sys_info[_wkq_thread] = True
sys_info[_wkq_error] = parse_error(e, 'workqueue')
# Look for conda and installed packages information
cmd = ('conda', 'info', '--json')
try:
conda_out = check_output(cmd)
except Exception as e:
_warning_log.append(f'Warning: Conda not available.\n Error was {e}\n')
# Conda is not available, try pip list to list installed packages
cmd = (sys.executable, '-m', 'pip', 'list')
try:
reqs = check_output(cmd)
except Exception as e:
_error_log.append(f'Error (pip): {e}')
else:
sys_info[_inst_pkg] = reqs.decode().splitlines()
else:
jsond = json.loads(conda_out.decode())
keys = {
'conda_build_version': _conda_build_ver,
'conda_env_version': _conda_env_ver,
'platform': _conda_platform,
'python_version': _conda_python_ver,
'root_writable': _conda_root_writable,
}
for conda_k, sysinfo_k in keys.items():
sys_info[sysinfo_k] = jsond.get(conda_k, 'N/A')
# Get info about packages in current environment
cmd = ('conda', 'list')
try:
conda_out = check_output(cmd)
except CalledProcessError as e:
_error_log.append(f'Error (conda): {e}')
else:
data = conda_out.decode().splitlines()
sys_info[_inst_pkg] = [l for l in data if not l.startswith('#')]
sys_info.update(get_os_spec_info(sys_info[_os_name]))
sys_info[_errors] = _error_log
sys_info[_warnings] = _warning_log
sys_info[_runtime] = (datetime.now() - sys_info[_start]).total_seconds()
return sys_info
def display_sysinfo(info=None, sep_pos=45):
class DisplayMap(dict):
display_map_flag = True
class DisplaySeq(tuple):
display_seq_flag = True
class DisplaySeqMaps(tuple):
display_seqmaps_flag = True
if info is None:
info = get_sysinfo()
fmt = f'%-{sep_pos}s : %-s'
MB = 1024**2
template = (
("-" * 80,),
("__Time Stamp__",),
("Report started (local time)", info.get(_start, '?')),
("UTC start time", info.get(_start_utc, '?')),
("Running time (s)", info.get(_runtime, '?')),
("",),
("__Hardware Information__",),
("Machine", info.get(_machine, '?')),
("CPU Name", info.get(_cpu_name, '?')),
("CPU Count", info.get(_cpu_count, '?')),
("Number of accessible CPUs", info.get(_cpus_allowed, '?')),
("List of accessible CPUs cores", info.get(_cpus_list, '?')),
("CFS Restrictions (CPUs worth of runtime)",
info.get(_cfs_restrict, 'None')),
("",),
("CPU Features", '\n'.join(
' ' * (sep_pos + 3) + l if i else l
for i, l in enumerate(
textwrap.wrap(
info.get(_cpu_features, '?'),
width=79 - sep_pos
)
)
)),
("",),
("Memory Total (MB)", info.get(_mem_total, 0) // MB or '?'),
("Memory Available (MB)"
if info.get(_os_name, '') != 'Darwin' or info.get(_psutil, False)
else "Free Memory (MB)", info.get(_mem_available, 0) // MB or '?'),
("",),
("__OS Information__",),
("Platform Name", info.get(_platform_name, '?')),
("Platform Release", info.get(_platform_release, '?')),
("OS Name", info.get(_os_name, '?')),
("OS Version", info.get(_os_version, '?')),
("OS Specific Version", info.get(_os_spec_version, '?')),
("Libc Version", info.get(_libc_version, '?')),
("",),
("__Python Information__",),
DisplayMap({k: v for k, v in info.items() if k.startswith('Python')}),
("",),
("__Numba Toolchain Versions__",),
("Numba Version", info.get(_numba_version, '?')),
("llvmlite Version", info.get(_llvmlite_version, '?')),
("",),
("__LLVM Information__",),
("LLVM Version", info.get(_llvm_version, '?')),
("",),
("__CUDA Information__",),
("CUDA Device Initialized", info.get(_cu_dev_init, '?')),
("CUDA Driver Version", info.get(_cu_drv_ver, '?')),
("CUDA Runtime Version", info.get(_cu_rt_ver, '?')),
("CUDA NVIDIA Bindings Available", info.get(_cu_nvidia_bindings, '?')),
("CUDA NVIDIA Bindings In Use",
info.get(_cu_nvidia_bindings_used, '?')),
("CUDA Minor Version Compatibility Available",
info.get(_cu_mvc_available, '?')),
("CUDA Minor Version Compatibility Needed",
info.get(_cu_mvc_needed, '?')),
("CUDA Minor Version Compatibility In Use",
info.get(_cu_mvc_in_use, '?')),
("CUDA Detect Output:",),
(info.get(_cu_detect_out, "None"),),
("CUDA Libraries Test Output:",),
(info.get(_cu_lib_test, "None"),),
("",),
("__NumPy Information__",),
("NumPy Version", info.get(_numpy_version, '?')),
("NumPy Supported SIMD features",
DisplaySeq(info.get(_numpy_supported_simd_features, [])
or ('None found.',))),
("NumPy Supported SIMD dispatch",
DisplaySeq(info.get(_numpy_supported_simd_dispatch, [])
or ('None found.',))),
("NumPy Supported SIMD baseline",
DisplaySeq(info.get(_numpy_supported_simd_baseline, [])
or ('None found.',))),
("NumPy AVX512_SKX support detected",
info.get(_numpy_AVX512_SKX_detected, '?')),
("",),
("__SVML Information__",),
("SVML State, config.USING_SVML", info.get(_svml_state, '?')),
("SVML Library Loaded", info.get(_svml_loaded, '?')),
("llvmlite Using SVML Patched LLVM", info.get(_llvm_svml_patched, '?')),
("SVML Operational", info.get(_svml_operational, '?')),
("",),
("__Threading Layer Information__",),
("TBB Threading Layer Available", info.get(_tbb_thread, '?')),
("+-->TBB imported successfully." if info.get(_tbb_thread, '?')
else f"+--> Disabled due to {info.get(_tbb_error, '?')}",),
("OpenMP Threading Layer Available", info.get(_openmp_thread, '?')),
(f"+-->Vendor: {info.get(_openmp_vendor, '?')}"
if info.get(_openmp_thread, False)
else f"+--> Disabled due to {info.get(_openmp_error, '?')}",),
("Workqueue Threading Layer Available", info.get(_wkq_thread, '?')),
("+-->Workqueue imported successfully." if info.get(_wkq_thread, False)
else f"+--> Disabled due to {info.get(_wkq_error, '?')}",),
("",),
("__Numba Environment Variable Information__",),
(DisplayMap(info.get(_numba_env_vars, {})) or ('None found.',)),
("",),
("__Conda Information__",),
(DisplayMap({k: v for k, v in info.items()
if k.startswith('Conda')}) or ("Conda not available.",)),
("",),
("__Installed Packages__",),
DisplaySeq(info.get(_inst_pkg, ("Couldn't retrieve packages info.",))),
("",),
("__Error log__" if info.get(_errors, [])
else "No errors reported.",),
DisplaySeq(info.get(_errors, [])),
("",),
("__Warning log__" if info.get(_warnings, [])
else "No warnings reported.",),
DisplaySeq(info.get(_warnings, [])),
("-" * 80,),
("If requested, please copy and paste the information between\n"
"the dashed (----) lines, or from a given specific section as\n"
"appropriate.\n\n"
"=============================================================\n"
"IMPORTANT: Please ensure that you are happy with sharing the\n"
"contents of the information present, any information that you\n"
"wish to keep private you should remove before sharing.\n"
"=============================================================\n",),
)
for t in template:
if hasattr(t, 'display_seq_flag'):
print(*t, sep='\n')
elif hasattr(t, 'display_map_flag'):
print(*tuple(fmt % (k, v) for (k, v) in t.items()), sep='\n')
elif hasattr(t, 'display_seqmaps_flag'):
for d in t:
print(*tuple(fmt % ('\t' + k, v) for (k, v) in d.items()),
sep='\n', end='\n')
elif len(t) == 2:
print(fmt % t)
else:
print(*t)
if __name__ == '__main__':
display_sysinfo()