Describe the bug
I'm hunting down some CI failures and have ended up here. It looks like py-cpuiunfo updated one of their dict keys ("brand" -> "brand_raw") which I will file a PR for in a moment. RDKit also made a release last week, but that does not seem to be the issue.
To Reproduce
after conda env create --name qcengine --file devtools/conda-envs/rdkit.yaml and activating it,
Click to expand
pytest && pytest -v --lf openmm_cmiles
============================================= test session starts ==============================================
platform darwin -- Python 3.8.3, pytest-5.4.3, py-1.8.2, pluggy-0.13.1
rootdir: /Users/mwt/software/QCEngine, inifile: setup.cfg
plugins: cov-2.10.0
collected 475 items / 4 skipped / 471 selected
qcengine/programs/tests/test_dftd3_mp2d.py sssss......................ssssssssssssssssssssssssssssssssss [ 12%]
ssssssssssssssssssssssssssssssssssssss [ 20%]
qcengine/programs/tests/test_nwchem.py sssss [ 21%]
qcengine/programs/tests/test_programs.py F.ssssssFFFFssFFFsss [ 26%]
qcengine/programs/tests/test_standard_suite.py sssssssssssssssssssssssssssssssssssssssssssssssssssssssss [ 38%]
ssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss [ 60%]
sssssssssssssssssssssssssssssssssssssssssssssssssssssss [ 71%]
qcengine/programs/tests/test_standard_suite_ccsd(t).py sssssssssss [ 73%]
qcengine/programs/tests/test_standard_suite_hf.py ssssssssssssssssssssssssssss [ 79%]
qcengine/programs/tests/test_turbomole.py sssssssss [ 81%]
qcengine/tests/test_cli.py .Fss [ 82%]
qcengine/tests/test_config.py .............F.. [ 85%]
qcengine/tests/test_harness_canonical.py sssssssssFsssssssssssFssssssssss.ss [ 93%]
qcengine/tests/test_mdi.py s [ 93%]
qcengine/tests/test_procedures.py sssssssssssssss [ 96%]
qcengine/tests/test_program_utils.py .ss...ss. [ 98%]
qcengine/tests/test_utils.py ....... [100%]
=================================================== FAILURES ===================================================
_______________________________________________ test_missing_key _______________________________________________
def test_missing_key():
> ret = qcng.compute({"hello": "hi"}, "bleh")
qcengine/programs/tests/test_programs.py:15:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
qcengine/compute.py:102: in compute
return handle_output_metadata(output_data, metadata, raise_error=raise_error, return_dict=return_dict)
qcengine/util.py:181: in handle_output_metadata
provenance_augments = get_provenance_augments()
qcengine/config.py:321: in get_provenance_augments
"cpu": get_global("cpu_brand"),
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
key = 'cpu_brand'
def get_global(key: Optional[str] = None) -> Union[str, Dict[str, Any]]:
import cpuinfo
import psutil
# TODO (wardlt): Implement a means of getting CPU information from compute nodes on clusters for MPI tasks
# The QC code runs on a different node than the node running this Python function, which may have different info
global _global_values
if _global_values is None:
_global_values = {}
_global_values["hostname"] = socket.gethostname()
_global_values["memory"] = round(psutil.virtual_memory().available / (1024 ** 3), 3)
_global_values["username"] = getpass.getuser()
# Work through VMs and logical cores.
if hasattr(psutil.Process(), "cpu_affinity"):
cpu_cnt = len(psutil.Process().cpu_affinity())
else:
cpu_cnt = psutil.cpu_count(logical=False)
if cpu_cnt is None:
cpu_cnt = psutil.cpu_count(logical=True)
_global_values["ncores"] = cpu_cnt
_global_values["nnodes"] = 1
_global_values["cpuinfo"] = cpuinfo.get_cpu_info()
> _global_values["cpu_brand"] = _global_values["cpuinfo"]["brand"]
E KeyError: 'brand'
qcengine/config.py:52: KeyError
_____________________________________________ test_rdkit_task[UFF] _____________________________________________
method = 'UFF'
@using("rdkit")
@pytest.mark.parametrize("method", ["UFF", "MMFF94", "MMFF94s"])
def test_rdkit_task(method):
input_data = {
"molecule": qcng.get_molecule("water"),
"driver": "gradient",
"model": {"method": method},
"keywords": {},
}
> ret = qcng.compute(input_data, "rdkit", raise_error=True)
qcengine/programs/tests/test_programs.py:143:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
qcengine/compute.py:102: in compute
return handle_output_metadata(output_data, metadata, raise_error=raise_error, return_dict=return_dict)
qcengine/util.py:181: in handle_output_metadata
provenance_augments = get_provenance_augments()
qcengine/config.py:321: in get_provenance_augments
"cpu": get_global("cpu_brand"),
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
key = 'cpu_brand'
def get_global(key: Optional[str] = None) -> Union[str, Dict[str, Any]]:
import cpuinfo
import psutil
# TODO (wardlt): Implement a means of getting CPU information from compute nodes on clusters for MPI tasks
# The QC code runs on a different node than the node running this Python function, which may have different info
global _global_values
if _global_values is None:
_global_values = {}
_global_values["hostname"] = socket.gethostname()
_global_values["memory"] = round(psutil.virtual_memory().available / (1024 ** 3), 3)
_global_values["username"] = getpass.getuser()
# Work through VMs and logical cores.
if hasattr(psutil.Process(), "cpu_affinity"):
cpu_cnt = len(psutil.Process().cpu_affinity())
else:
cpu_cnt = psutil.cpu_count(logical=False)
if cpu_cnt is None:
cpu_cnt = psutil.cpu_count(logical=True)
_global_values["ncores"] = cpu_cnt
_global_values["nnodes"] = 1
_global_values["cpuinfo"] = cpuinfo.get_cpu_info()
_global_values["cpu_brand"] = _global_values["cpuinfo"]["brand"]
if key is None:
return _global_values.copy()
else:
> return _global_values[key]
E KeyError: 'cpu_brand'
qcengine/config.py:57: KeyError
___________________________________________ test_rdkit_task[MMFF94] ____________________________________________
method = 'MMFF94'
@using("rdkit")
@pytest.mark.parametrize("method", ["UFF", "MMFF94", "MMFF94s"])
def test_rdkit_task(method):
input_data = {
"molecule": qcng.get_molecule("water"),
"driver": "gradient",
"model": {"method": method},
"keywords": {},
}
> ret = qcng.compute(input_data, "rdkit", raise_error=True)
qcengine/programs/tests/test_programs.py:143:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
qcengine/compute.py:102: in compute
return handle_output_metadata(output_data, metadata, raise_error=raise_error, return_dict=return_dict)
qcengine/util.py:181: in handle_output_metadata
provenance_augments = get_provenance_augments()
qcengine/config.py:321: in get_provenance_augments
"cpu": get_global("cpu_brand"),
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
key = 'cpu_brand'
def get_global(key: Optional[str] = None) -> Union[str, Dict[str, Any]]:
import cpuinfo
import psutil
# TODO (wardlt): Implement a means of getting CPU information from compute nodes on clusters for MPI tasks
# The QC code runs on a different node than the node running this Python function, which may have different info
global _global_values
if _global_values is None:
_global_values = {}
_global_values["hostname"] = socket.gethostname()
_global_values["memory"] = round(psutil.virtual_memory().available / (1024 ** 3), 3)
_global_values["username"] = getpass.getuser()
# Work through VMs and logical cores.
if hasattr(psutil.Process(), "cpu_affinity"):
cpu_cnt = len(psutil.Process().cpu_affinity())
else:
cpu_cnt = psutil.cpu_count(logical=False)
if cpu_cnt is None:
cpu_cnt = psutil.cpu_count(logical=True)
_global_values["ncores"] = cpu_cnt
_global_values["nnodes"] = 1
_global_values["cpuinfo"] = cpuinfo.get_cpu_info()
_global_values["cpu_brand"] = _global_values["cpuinfo"]["brand"]
if key is None:
return _global_values.copy()
else:
> return _global_values[key]
E KeyError: 'cpu_brand'
qcengine/config.py:57: KeyError
___________________________________________ test_rdkit_task[MMFF94s] ___________________________________________
method = 'MMFF94s'
@using("rdkit")
@pytest.mark.parametrize("method", ["UFF", "MMFF94", "MMFF94s"])
def test_rdkit_task(method):
input_data = {
"molecule": qcng.get_molecule("water"),
"driver": "gradient",
"model": {"method": method},
"keywords": {},
}
> ret = qcng.compute(input_data, "rdkit", raise_error=True)
qcengine/programs/tests/test_programs.py:143:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
qcengine/compute.py:102: in compute
return handle_output_metadata(output_data, metadata, raise_error=raise_error, return_dict=return_dict)
qcengine/util.py:181: in handle_output_metadata
provenance_augments = get_provenance_augments()
qcengine/config.py:321: in get_provenance_augments
"cpu": get_global("cpu_brand"),
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
key = 'cpu_brand'
def get_global(key: Optional[str] = None) -> Union[str, Dict[str, Any]]:
import cpuinfo
import psutil
# TODO (wardlt): Implement a means of getting CPU information from compute nodes on clusters for MPI tasks
# The QC code runs on a different node than the node running this Python function, which may have different info
global _global_values
if _global_values is None:
_global_values = {}
_global_values["hostname"] = socket.gethostname()
_global_values["memory"] = round(psutil.virtual_memory().available / (1024 ** 3), 3)
_global_values["username"] = getpass.getuser()
# Work through VMs and logical cores.
if hasattr(psutil.Process(), "cpu_affinity"):
cpu_cnt = len(psutil.Process().cpu_affinity())
else:
cpu_cnt = psutil.cpu_count(logical=False)
if cpu_cnt is None:
cpu_cnt = psutil.cpu_count(logical=True)
_global_values["ncores"] = cpu_cnt
_global_values["nnodes"] = 1
_global_values["cpuinfo"] = cpuinfo.get_cpu_info()
_global_values["cpu_brand"] = _global_values["cpuinfo"]["brand"]
if key is None:
return _global_values.copy()
else:
> return _global_values[key]
E KeyError: 'cpu_brand'
qcengine/config.py:57: KeyError
________________________________________ test_rdkit_connectivity_error _________________________________________
@using("rdkit")
def test_rdkit_connectivity_error():
input_data = {
"molecule": qcng.get_molecule("water").dict(),
"driver": "energy",
"model": {"method": "UFF", "basis": ""},
"keywords": {},
}
del input_data["molecule"]["connectivity"]
> ret = qcng.compute(input_data, "rdkit")
qcengine/programs/tests/test_programs.py:158:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
qcengine/compute.py:102: in compute
return handle_output_metadata(output_data, metadata, raise_error=raise_error, return_dict=return_dict)
qcengine/util.py:181: in handle_output_metadata
provenance_augments = get_provenance_augments()
qcengine/config.py:321: in get_provenance_augments
"cpu": get_global("cpu_brand"),
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
key = 'cpu_brand'
def get_global(key: Optional[str] = None) -> Union[str, Dict[str, Any]]:
import cpuinfo
import psutil
# TODO (wardlt): Implement a means of getting CPU information from compute nodes on clusters for MPI tasks
# The QC code runs on a different node than the node running this Python function, which may have different info
global _global_values
if _global_values is None:
_global_values = {}
_global_values["hostname"] = socket.gethostname()
_global_values["memory"] = round(psutil.virtual_memory().available / (1024 ** 3), 3)
_global_values["username"] = getpass.getuser()
# Work through VMs and logical cores.
if hasattr(psutil.Process(), "cpu_affinity"):
cpu_cnt = len(psutil.Process().cpu_affinity())
else:
cpu_cnt = psutil.cpu_count(logical=False)
if cpu_cnt is None:
cpu_cnt = psutil.cpu_count(logical=True)
_global_values["ncores"] = cpu_cnt
_global_values["nnodes"] = 1
_global_values["cpuinfo"] = cpuinfo.get_cpu_info()
_global_values["cpu_brand"] = _global_values["cpuinfo"]["brand"]
if key is None:
return _global_values.copy()
else:
> return _global_values[key]
E KeyError: 'cpu_brand'
qcengine/config.py:57: KeyError
________________________________________ test_random_failure_no_retries ________________________________________
failure_engine = FailEngine(name='testing_random_name', scratch=False, thread_safe=True, thread_parallel=False, node_parallel=False, managed_memory=False, extras=None, iter_modes=[], ncalls=1, start_distance=5, equilibrium_distance=4)
def test_random_failure_no_retries(failure_engine):
failure_engine.iter_modes = ["input_error"]
> ret = qcng.compute(failure_engine.get_job(), failure_engine.name, raise_error=False)
qcengine/programs/tests/test_programs.py:210:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
qcengine/compute.py:102: in compute
return handle_output_metadata(output_data, metadata, raise_error=raise_error, return_dict=return_dict)
qcengine/util.py:181: in handle_output_metadata
provenance_augments = get_provenance_augments()
qcengine/config.py:321: in get_provenance_augments
"cpu": get_global("cpu_brand"),
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
key = 'cpu_brand'
def get_global(key: Optional[str] = None) -> Union[str, Dict[str, Any]]:
import cpuinfo
import psutil
# TODO (wardlt): Implement a means of getting CPU information from compute nodes on clusters for MPI tasks
# The QC code runs on a different node than the node running this Python function, which may have different info
global _global_values
if _global_values is None:
_global_values = {}
_global_values["hostname"] = socket.gethostname()
_global_values["memory"] = round(psutil.virtual_memory().available / (1024 ** 3), 3)
_global_values["username"] = getpass.getuser()
# Work through VMs and logical cores.
if hasattr(psutil.Process(), "cpu_affinity"):
cpu_cnt = len(psutil.Process().cpu_affinity())
else:
cpu_cnt = psutil.cpu_count(logical=False)
if cpu_cnt is None:
cpu_cnt = psutil.cpu_count(logical=True)
_global_values["ncores"] = cpu_cnt
_global_values["nnodes"] = 1
_global_values["cpuinfo"] = cpuinfo.get_cpu_info()
_global_values["cpu_brand"] = _global_values["cpuinfo"]["brand"]
if key is None:
return _global_values.copy()
else:
> return _global_values[key]
E KeyError: 'cpu_brand'
qcengine/config.py:57: KeyError
_______________________________________ test_random_failure_with_retries _______________________________________
failure_engine = FailEngine(name='testing_random_name', scratch=False, thread_safe=True, thread_parallel=False, node_parallel=False, managed_memory=False, extras=None, iter_modes=[], ncalls=3, start_distance=5, equilibrium_distance=4)
def test_random_failure_with_retries(failure_engine):
failure_engine.iter_modes = ["random_error", "random_error", "random_error"]
> ret = qcng.compute(failure_engine.get_job(), failure_engine.name, raise_error=False, local_options={"retries": 2})
qcengine/programs/tests/test_programs.py:223:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
qcengine/compute.py:102: in compute
return handle_output_metadata(output_data, metadata, raise_error=raise_error, return_dict=return_dict)
qcengine/util.py:181: in handle_output_metadata
provenance_augments = get_provenance_augments()
qcengine/config.py:321: in get_provenance_augments
"cpu": get_global("cpu_brand"),
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
key = 'cpu_brand'
def get_global(key: Optional[str] = None) -> Union[str, Dict[str, Any]]:
import cpuinfo
import psutil
# TODO (wardlt): Implement a means of getting CPU information from compute nodes on clusters for MPI tasks
# The QC code runs on a different node than the node running this Python function, which may have different info
global _global_values
if _global_values is None:
_global_values = {}
_global_values["hostname"] = socket.gethostname()
_global_values["memory"] = round(psutil.virtual_memory().available / (1024 ** 3), 3)
_global_values["username"] = getpass.getuser()
# Work through VMs and logical cores.
if hasattr(psutil.Process(), "cpu_affinity"):
cpu_cnt = len(psutil.Process().cpu_affinity())
else:
cpu_cnt = psutil.cpu_count(logical=False)
if cpu_cnt is None:
cpu_cnt = psutil.cpu_count(logical=True)
_global_values["ncores"] = cpu_cnt
_global_values["nnodes"] = 1
_global_values["cpuinfo"] = cpuinfo.get_cpu_info()
_global_values["cpu_brand"] = _global_values["cpuinfo"]["brand"]
if key is None:
return _global_values.copy()
else:
> return _global_values[key]
E KeyError: 'cpu_brand'
qcengine/config.py:57: KeyError
_______________________________________ test_random_failure_with_success _______________________________________
failure_engine = FailEngine(name='testing_random_name', scratch=False, thread_safe=True, thread_parallel=False, node_parallel=False, managed_memory=False, extras=None, iter_modes=[], ncalls=2, start_distance=5, equilibrium_distance=4)
def test_random_failure_with_success(failure_engine):
failure_engine.iter_modes = ["random_error", "pass"]
failure_engine.ncalls = 0
> ret = qcng.compute(failure_engine.get_job(), failure_engine.name, raise_error=False, local_options={"retries": 1})
qcengine/programs/tests/test_programs.py:237:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
qcengine/compute.py:102: in compute
return handle_output_metadata(output_data, metadata, raise_error=raise_error, return_dict=return_dict)
qcengine/util.py:181: in handle_output_metadata
provenance_augments = get_provenance_augments()
qcengine/config.py:321: in get_provenance_augments
"cpu": get_global("cpu_brand"),
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
key = 'cpu_brand'
def get_global(key: Optional[str] = None) -> Union[str, Dict[str, Any]]:
import cpuinfo
import psutil
# TODO (wardlt): Implement a means of getting CPU information from compute nodes on clusters for MPI tasks
# The QC code runs on a different node than the node running this Python function, which may have different info
global _global_values
if _global_values is None:
_global_values = {}
_global_values["hostname"] = socket.gethostname()
_global_values["memory"] = round(psutil.virtual_memory().available / (1024 ** 3), 3)
_global_values["username"] = getpass.getuser()
# Work through VMs and logical cores.
if hasattr(psutil.Process(), "cpu_affinity"):
cpu_cnt = len(psutil.Process().cpu_affinity())
else:
cpu_cnt = psutil.cpu_count(logical=False)
if cpu_cnt is None:
cpu_cnt = psutil.cpu_count(logical=True)
_global_values["ncores"] = cpu_cnt
_global_values["nnodes"] = 1
_global_values["cpuinfo"] = cpuinfo.get_cpu_info()
_global_values["cpu_brand"] = _global_values["cpuinfo"]["brand"]
if key is None:
return _global_values.copy()
else:
> return _global_values[key]
E KeyError: 'cpu_brand'
qcengine/config.py:57: KeyError
__________________________________________________ test_info ___________________________________________________
def test_info():
"""Test for qcengine info"""
outputs = []
for arg in cli.info_choices:
> output = run_qcengine_cli(["info", arg])
qcengine/tests/test_cli.py:50:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
qcengine/tests/test_cli.py:35: in run_qcengine_cli
return subprocess.check_output([sys.executable, "-m", "qcengine"] + args, input=stdin)
../miniconda3/envs/qcengine/lib/python3.8/subprocess.py:411: in check_output
return run(*popenargs, stdout=PIPE, timeout=timeout, check=True,
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
input = b'', capture_output = False, timeout = None, check = True
popenargs = (['/Users/mwt/software/miniconda3/envs/qcengine/bin/python', '-m', 'qcengine', 'info', 'config'],)
kwargs = {'stdin': -1, 'stdout': -1}, process =
stdout = b'>>> Configuration information\n\n', stderr = None, retcode = 1
def run(*popenargs,
input=None, capture_output=False, timeout=None, check=False, **kwargs):
"""Run command with arguments and return a CompletedProcess instance.
The returned instance will have attributes args, returncode, stdout and
stderr. By default, stdout and stderr are not captured, and those attributes
will be None. Pass stdout=PIPE and/or stderr=PIPE in order to capture them.
If check is True and the exit code was non-zero, it raises a
CalledProcessError. The CalledProcessError object will have the return code
in the returncode attribute, and output & stderr attributes if those streams
were captured.
If timeout is given, and the process takes too long, a TimeoutExpired
exception will be raised.
There is an optional argument "input", allowing you to
pass bytes or a string to the subprocess's stdin. If you use this argument
you may not also use the Popen constructor's "stdin" argument, as
it will be used internally.
By default, all communication is in bytes, and therefore any "input" should
be bytes, and the stdout and stderr will be bytes. If in text mode, any
"input" should be a string, and stdout and stderr will be strings decoded
according to locale encoding, or by "encoding" if set. Text mode is
triggered by setting any of text, encoding, errors or universal_newlines.
The other arguments are the same as for the Popen constructor.
"""
if input is not None:
if kwargs.get('stdin') is not None:
raise ValueError('stdin and input arguments may not both be used.')
kwargs['stdin'] = PIPE
if capture_output:
if kwargs.get('stdout') is not None or kwargs.get('stderr') is not None:
raise ValueError('stdout and stderr arguments may not be used '
'with capture_output.')
kwargs['stdout'] = PIPE
kwargs['stderr'] = PIPE
with Popen(*popenargs, **kwargs) as process:
try:
stdout, stderr = process.communicate(input, timeout=timeout)
except TimeoutExpired as exc:
process.kill()
if _mswindows:
# Windows accumulates the output in a single blocking
# read() call run on child threads, with the timeout
# being done in a join() on those threads. communicate()
# _after_ kill() is required to collect that and add it
# to the exception.
exc.stdout, exc.stderr = process.communicate()
else:
# POSIX _communicate already populated the output so
# far into the TimeoutExpired exception.
process.wait()
raise
except: # Including KeyboardInterrupt, communicate handled that.
process.kill()
# We don't call process.wait() as .__exit__ does that for us.
raise
retcode = process.poll()
if check and retcode:
> raise CalledProcessError(retcode, process.args,
output=stdout, stderr=stderr)
E subprocess.CalledProcessError: Command '['/Users/mwt/software/miniconda3/envs/qcengine/bin/python', '-m', 'qcengine', 'info', 'config']' returned non-zero exit status 1.
../miniconda3/envs/qcengine/lib/python3.8/subprocess.py:512: CalledProcessError
--------------------------------------------- Captured stderr call ---------------------------------------------
Traceback (most recent call last):
File "/Users/mwt/software/miniconda3/envs/qcengine/lib/python3.8/runpy.py", line 194, in _run_module_as_main
return _run_code(code, main_globals, None,
File "/Users/mwt/software/miniconda3/envs/qcengine/lib/python3.8/runpy.py", line 87, in _run_code
exec(code, run_globals)
File "/Users/mwt/software/QCEngine/qcengine/__main__.py", line 3, in
qcengine.cli.main()
File "/Users/mwt/software/QCEngine/qcengine/cli.py", line 163, in main
info_cli(args)
File "/Users/mwt/software/QCEngine/qcengine/cli.py", line 132, in info_cli
print(global_repr())
File "/Users/mwt/software/QCEngine/qcengine/config.py", line 199, in global_repr
prov = get_provenance_augments()
File "/Users/mwt/software/QCEngine/qcengine/config.py", line 321, in get_provenance_augments
"cpu": get_global("cpu_brand"),
File "/Users/mwt/software/QCEngine/qcengine/config.py", line 52, in get_global
_global_values["cpu_brand"] = _global_values["cpuinfo"]["brand"]
KeyError: 'brand'
_______________________________________________ test_global_repr _______________________________________________
def test_global_repr():
> assert isinstance(qcng.config.global_repr(), str)
qcengine/tests/test_config.py:215:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
qcengine/config.py:199: in global_repr
prov = get_provenance_augments()
qcengine/config.py:321: in get_provenance_augments
"cpu": get_global("cpu_brand"),
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
key = 'cpu_brand'
def get_global(key: Optional[str] = None) -> Union[str, Dict[str, Any]]:
import cpuinfo
import psutil
# TODO (wardlt): Implement a means of getting CPU information from compute nodes on clusters for MPI tasks
# The QC code runs on a different node than the node running this Python function, which may have different info
global _global_values
if _global_values is None:
_global_values = {}
_global_values["hostname"] = socket.gethostname()
_global_values["memory"] = round(psutil.virtual_memory().available / (1024 ** 3), 3)
_global_values["username"] = getpass.getuser()
# Work through VMs and logical cores.
if hasattr(psutil.Process(), "cpu_affinity"):
cpu_cnt = len(psutil.Process().cpu_affinity())
else:
cpu_cnt = psutil.cpu_count(logical=False)
if cpu_cnt is None:
cpu_cnt = psutil.cpu_count(logical=True)
_global_values["ncores"] = cpu_cnt
_global_values["nnodes"] = 1
_global_values["cpuinfo"] = cpuinfo.get_cpu_info()
_global_values["cpu_brand"] = _global_values["cpuinfo"]["brand"]
if key is None:
return _global_values.copy()
else:
> return _global_values[key]
E KeyError: 'cpu_brand'
qcengine/config.py:57: KeyError
______________________________________ test_compute_energy[rdkit-model9] _______________________________________
program = 'rdkit', model = {'method': 'UFF'}
@pytest.mark.parametrize("program, model", _canonical_methods)
def test_compute_energy(program, model):
if not has_program(program):
pytest.skip("Program '{}' not found.".format(program))
molecule = _get_molecule(program)
inp = AtomicInput(molecule=molecule, driver="energy", model=model)
> ret = qcng.compute(inp, program, raise_error=True)
qcengine/tests/test_harness_canonical.py:44:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
qcengine/compute.py:102: in compute
return handle_output_metadata(output_data, metadata, raise_error=raise_error, return_dict=return_dict)
qcengine/util.py:181: in handle_output_metadata
provenance_augments = get_provenance_augments()
qcengine/config.py:321: in get_provenance_augments
"cpu": get_global("cpu_brand"),
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
key = 'cpu_brand'
def get_global(key: Optional[str] = None) -> Union[str, Dict[str, Any]]:
import cpuinfo
import psutil
# TODO (wardlt): Implement a means of getting CPU information from compute nodes on clusters for MPI tasks
# The QC code runs on a different node than the node running this Python function, which may have different info
global _global_values
if _global_values is None:
_global_values = {}
_global_values["hostname"] = socket.gethostname()
_global_values["memory"] = round(psutil.virtual_memory().available / (1024 ** 3), 3)
_global_values["username"] = getpass.getuser()
# Work through VMs and logical cores.
if hasattr(psutil.Process(), "cpu_affinity"):
cpu_cnt = len(psutil.Process().cpu_affinity())
else:
cpu_cnt = psutil.cpu_count(logical=False)
if cpu_cnt is None:
cpu_cnt = psutil.cpu_count(logical=True)
_global_values["ncores"] = cpu_cnt
_global_values["nnodes"] = 1
_global_values["cpuinfo"] = cpuinfo.get_cpu_info()
_global_values["cpu_brand"] = _global_values["cpuinfo"]["brand"]
if key is None:
return _global_values.copy()
else:
> return _global_values[key]
E KeyError: 'cpu_brand'
qcengine/config.py:57: KeyError
_____________________________________ test_compute_gradient[rdkit-model9] ______________________________________
program = 'rdkit', model = {'method': 'UFF'}
@pytest.mark.parametrize("program, model", _canonical_methods)
def test_compute_gradient(program, model):
if not has_program(program):
pytest.skip("Program '{}' not found.".format(program))
molecule = _get_molecule(program)
inp = AtomicInput(molecule=molecule, driver="gradient", model=model, extras={"mytag": "something"})
> ret = qcng.compute(inp, program, raise_error=True)
qcengine/tests/test_harness_canonical.py:58:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
qcengine/compute.py:102: in compute
return handle_output_metadata(output_data, metadata, raise_error=raise_error, return_dict=return_dict)
qcengine/util.py:181: in handle_output_metadata
provenance_augments = get_provenance_augments()
qcengine/config.py:321: in get_provenance_augments
"cpu": get_global("cpu_brand"),
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
key = 'cpu_brand'
def get_global(key: Optional[str] = None) -> Union[str, Dict[str, Any]]:
import cpuinfo
import psutil
# TODO (wardlt): Implement a means of getting CPU information from compute nodes on clusters for MPI tasks
# The QC code runs on a different node than the node running this Python function, which may have different info
global _global_values
if _global_values is None:
_global_values = {}
_global_values["hostname"] = socket.gethostname()
_global_values["memory"] = round(psutil.virtual_memory().available / (1024 ** 3), 3)
_global_values["username"] = getpass.getuser()
# Work through VMs and logical cores.
if hasattr(psutil.Process(), "cpu_affinity"):
cpu_cnt = len(psutil.Process().cpu_affinity())
else:
cpu_cnt = psutil.cpu_count(logical=False)
if cpu_cnt is None:
cpu_cnt = psutil.cpu_count(logical=True)
_global_values["ncores"] = cpu_cnt
_global_values["nnodes"] = 1
_global_values["cpuinfo"] = cpuinfo.get_cpu_info()
_global_values["cpu_brand"] = _global_values["cpuinfo"]["brand"]
if key is None:
return _global_values.copy()
else:
> return _global_values[key]
E KeyError: 'cpu_brand'
qcengine/config.py:57: KeyError
=============================================== warnings summary ===============================================
qcengine/programs/tests/test_programs.py::test_rdkit_task[UFF]
:219: RuntimeWarning: numpy.ufunc size changed, may indicate binary incompatibility. Expected 192 from C header, got 216 from PyObject
-- Docs: https://docs.pytest.org/en/latest/warnings.html
=========================================== short test summary info ============================================
FAILED qcengine/programs/tests/test_programs.py::test_missing_key - KeyError: 'brand'
FAILED qcengine/programs/tests/test_programs.py::test_rdkit_task[UFF] - KeyError: 'cpu_brand'
FAILED qcengine/programs/tests/test_programs.py::test_rdkit_task[MMFF94] - KeyError: 'cpu_brand'
FAILED qcengine/programs/tests/test_programs.py::test_rdkit_task[MMFF94s] - KeyError: 'cpu_brand'
FAILED qcengine/programs/tests/test_programs.py::test_rdkit_connectivity_error - KeyError: 'cpu_brand'
FAILED qcengine/programs/tests/test_programs.py::test_random_failure_no_retries - KeyError: 'cpu_brand'
FAILED qcengine/programs/tests/test_programs.py::test_random_failure_with_retries - KeyError: 'cpu_brand'
FAILED qcengine/programs/tests/test_programs.py::test_random_failure_with_success - KeyError: 'cpu_brand'
FAILED qcengine/tests/test_cli.py::test_info - subprocess.CalledProcessError: Command '['/Users/mwt/software/...
FAILED qcengine/tests/test_config.py::test_global_repr - KeyError: 'cpu_brand'
FAILED qcengine/tests/test_harness_canonical.py::test_compute_energy[rdkit-model9] - KeyError: 'cpu_brand'
FAILED qcengine/tests/test_harness_canonical.py::test_compute_gradient[rdkit-model9] - KeyError: 'cpu_brand'
============================ 12 failed, 52 passed, 415 skipped, 1 warning in 9.20s =============================
Describe the bug I'm hunting down some CI failures and have ended up here. It looks like
py-cpuiunfo
updated one of their dict keys ("brand"
->"brand_raw"
) which I will file a PR for in a moment. RDKit also made a release last week, but that does not seem to be the issue.To Reproduce after
conda env create --name qcengine --file devtools/conda-envs/rdkit.yaml
and activating it,Click to expand
pytest && pytest -v --lf openmm_cmiles ============================================= test session starts ============================================== platform darwin -- Python 3.8.3, pytest-5.4.3, py-1.8.2, pluggy-0.13.1 rootdir: /Users/mwt/software/QCEngine, inifile: setup.cfg plugins: cov-2.10.0 collected 475 items / 4 skipped / 471 selected qcengine/programs/tests/test_dftd3_mp2d.py sssss......................ssssssssssssssssssssssssssssssssss [ 12%] ssssssssssssssssssssssssssssssssssssss [ 20%] qcengine/programs/tests/test_nwchem.py sssss [ 21%] qcengine/programs/tests/test_programs.py F.ssssssFFFFssFFFsss [ 26%] qcengine/programs/tests/test_standard_suite.py sssssssssssssssssssssssssssssssssssssssssssssssssssssssss [ 38%] ssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss [ 60%] sssssssssssssssssssssssssssssssssssssssssssssssssssssss [ 71%] qcengine/programs/tests/test_standard_suite_ccsd(t).py sssssssssss [ 73%] qcengine/programs/tests/test_standard_suite_hf.py ssssssssssssssssssssssssssss [ 79%] qcengine/programs/tests/test_turbomole.py sssssssss [ 81%] qcengine/tests/test_cli.py .Fss [ 82%] qcengine/tests/test_config.py .............F.. [ 85%] qcengine/tests/test_harness_canonical.py sssssssssFsssssssssssFssssssssss.ss [ 93%] qcengine/tests/test_mdi.py s [ 93%] qcengine/tests/test_procedures.py sssssssssssssss [ 96%] qcengine/tests/test_program_utils.py .ss...ss. [ 98%] qcengine/tests/test_utils.py ....... [100%] =================================================== FAILURES =================================================== _______________________________________________ test_missing_key _______________________________________________ def test_missing_key(): > ret = qcng.compute({"hello": "hi"}, "bleh") qcengine/programs/tests/test_programs.py:15: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ qcengine/compute.py:102: in compute return handle_output_metadata(output_data, metadata, raise_error=raise_error, return_dict=return_dict) qcengine/util.py:181: in handle_output_metadata provenance_augments = get_provenance_augments() qcengine/config.py:321: in get_provenance_augments "cpu": get_global("cpu_brand"), _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ key = 'cpu_brand' def get_global(key: Optional[str] = None) -> Union[str, Dict[str, Any]]: import cpuinfo import psutil # TODO (wardlt): Implement a means of getting CPU information from compute nodes on clusters for MPI tasks # The QC code runs on a different node than the node running this Python function, which may have different info global _global_values if _global_values is None: _global_values = {} _global_values["hostname"] = socket.gethostname() _global_values["memory"] = round(psutil.virtual_memory().available / (1024 ** 3), 3) _global_values["username"] = getpass.getuser() # Work through VMs and logical cores. if hasattr(psutil.Process(), "cpu_affinity"): cpu_cnt = len(psutil.Process().cpu_affinity()) else: cpu_cnt = psutil.cpu_count(logical=False) if cpu_cnt is None: cpu_cnt = psutil.cpu_count(logical=True) _global_values["ncores"] = cpu_cnt _global_values["nnodes"] = 1 _global_values["cpuinfo"] = cpuinfo.get_cpu_info() > _global_values["cpu_brand"] = _global_values["cpuinfo"]["brand"] E KeyError: 'brand' qcengine/config.py:52: KeyError _____________________________________________ test_rdkit_task[UFF] _____________________________________________ method = 'UFF' @using("rdkit") @pytest.mark.parametrize("method", ["UFF", "MMFF94", "MMFF94s"]) def test_rdkit_task(method): input_data = { "molecule": qcng.get_molecule("water"), "driver": "gradient", "model": {"method": method}, "keywords": {}, } > ret = qcng.compute(input_data, "rdkit", raise_error=True) qcengine/programs/tests/test_programs.py:143: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ qcengine/compute.py:102: in compute return handle_output_metadata(output_data, metadata, raise_error=raise_error, return_dict=return_dict) qcengine/util.py:181: in handle_output_metadata provenance_augments = get_provenance_augments() qcengine/config.py:321: in get_provenance_augments "cpu": get_global("cpu_brand"), _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ key = 'cpu_brand' def get_global(key: Optional[str] = None) -> Union[str, Dict[str, Any]]: import cpuinfo import psutil # TODO (wardlt): Implement a means of getting CPU information from compute nodes on clusters for MPI tasks # The QC code runs on a different node than the node running this Python function, which may have different info global _global_values if _global_values is None: _global_values = {} _global_values["hostname"] = socket.gethostname() _global_values["memory"] = round(psutil.virtual_memory().available / (1024 ** 3), 3) _global_values["username"] = getpass.getuser() # Work through VMs and logical cores. if hasattr(psutil.Process(), "cpu_affinity"): cpu_cnt = len(psutil.Process().cpu_affinity()) else: cpu_cnt = psutil.cpu_count(logical=False) if cpu_cnt is None: cpu_cnt = psutil.cpu_count(logical=True) _global_values["ncores"] = cpu_cnt _global_values["nnodes"] = 1 _global_values["cpuinfo"] = cpuinfo.get_cpu_info() _global_values["cpu_brand"] = _global_values["cpuinfo"]["brand"] if key is None: return _global_values.copy() else: > return _global_values[key] E KeyError: 'cpu_brand' qcengine/config.py:57: KeyError ___________________________________________ test_rdkit_task[MMFF94] ____________________________________________ method = 'MMFF94' @using("rdkit") @pytest.mark.parametrize("method", ["UFF", "MMFF94", "MMFF94s"]) def test_rdkit_task(method): input_data = { "molecule": qcng.get_molecule("water"), "driver": "gradient", "model": {"method": method}, "keywords": {}, } > ret = qcng.compute(input_data, "rdkit", raise_error=True) qcengine/programs/tests/test_programs.py:143: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ qcengine/compute.py:102: in compute return handle_output_metadata(output_data, metadata, raise_error=raise_error, return_dict=return_dict) qcengine/util.py:181: in handle_output_metadata provenance_augments = get_provenance_augments() qcengine/config.py:321: in get_provenance_augments "cpu": get_global("cpu_brand"), _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ key = 'cpu_brand' def get_global(key: Optional[str] = None) -> Union[str, Dict[str, Any]]: import cpuinfo import psutil # TODO (wardlt): Implement a means of getting CPU information from compute nodes on clusters for MPI tasks # The QC code runs on a different node than the node running this Python function, which may have different info global _global_values if _global_values is None: _global_values = {} _global_values["hostname"] = socket.gethostname() _global_values["memory"] = round(psutil.virtual_memory().available / (1024 ** 3), 3) _global_values["username"] = getpass.getuser() # Work through VMs and logical cores. if hasattr(psutil.Process(), "cpu_affinity"): cpu_cnt = len(psutil.Process().cpu_affinity()) else: cpu_cnt = psutil.cpu_count(logical=False) if cpu_cnt is None: cpu_cnt = psutil.cpu_count(logical=True) _global_values["ncores"] = cpu_cnt _global_values["nnodes"] = 1 _global_values["cpuinfo"] = cpuinfo.get_cpu_info() _global_values["cpu_brand"] = _global_values["cpuinfo"]["brand"] if key is None: return _global_values.copy() else: > return _global_values[key] E KeyError: 'cpu_brand' qcengine/config.py:57: KeyError ___________________________________________ test_rdkit_task[MMFF94s] ___________________________________________ method = 'MMFF94s' @using("rdkit") @pytest.mark.parametrize("method", ["UFF", "MMFF94", "MMFF94s"]) def test_rdkit_task(method): input_data = { "molecule": qcng.get_molecule("water"), "driver": "gradient", "model": {"method": method}, "keywords": {}, } > ret = qcng.compute(input_data, "rdkit", raise_error=True) qcengine/programs/tests/test_programs.py:143: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ qcengine/compute.py:102: in compute return handle_output_metadata(output_data, metadata, raise_error=raise_error, return_dict=return_dict) qcengine/util.py:181: in handle_output_metadata provenance_augments = get_provenance_augments() qcengine/config.py:321: in get_provenance_augments "cpu": get_global("cpu_brand"), _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ key = 'cpu_brand' def get_global(key: Optional[str] = None) -> Union[str, Dict[str, Any]]: import cpuinfo import psutil # TODO (wardlt): Implement a means of getting CPU information from compute nodes on clusters for MPI tasks # The QC code runs on a different node than the node running this Python function, which may have different info global _global_values if _global_values is None: _global_values = {} _global_values["hostname"] = socket.gethostname() _global_values["memory"] = round(psutil.virtual_memory().available / (1024 ** 3), 3) _global_values["username"] = getpass.getuser() # Work through VMs and logical cores. if hasattr(psutil.Process(), "cpu_affinity"): cpu_cnt = len(psutil.Process().cpu_affinity()) else: cpu_cnt = psutil.cpu_count(logical=False) if cpu_cnt is None: cpu_cnt = psutil.cpu_count(logical=True) _global_values["ncores"] = cpu_cnt _global_values["nnodes"] = 1 _global_values["cpuinfo"] = cpuinfo.get_cpu_info() _global_values["cpu_brand"] = _global_values["cpuinfo"]["brand"] if key is None: return _global_values.copy() else: > return _global_values[key] E KeyError: 'cpu_brand' qcengine/config.py:57: KeyError ________________________________________ test_rdkit_connectivity_error _________________________________________ @using("rdkit") def test_rdkit_connectivity_error(): input_data = { "molecule": qcng.get_molecule("water").dict(), "driver": "energy", "model": {"method": "UFF", "basis": ""}, "keywords": {}, } del input_data["molecule"]["connectivity"] > ret = qcng.compute(input_data, "rdkit") qcengine/programs/tests/test_programs.py:158: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ qcengine/compute.py:102: in compute return handle_output_metadata(output_data, metadata, raise_error=raise_error, return_dict=return_dict) qcengine/util.py:181: in handle_output_metadata provenance_augments = get_provenance_augments() qcengine/config.py:321: in get_provenance_augments "cpu": get_global("cpu_brand"), _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ key = 'cpu_brand' def get_global(key: Optional[str] = None) -> Union[str, Dict[str, Any]]: import cpuinfo import psutil # TODO (wardlt): Implement a means of getting CPU information from compute nodes on clusters for MPI tasks # The QC code runs on a different node than the node running this Python function, which may have different info global _global_values if _global_values is None: _global_values = {} _global_values["hostname"] = socket.gethostname() _global_values["memory"] = round(psutil.virtual_memory().available / (1024 ** 3), 3) _global_values["username"] = getpass.getuser() # Work through VMs and logical cores. if hasattr(psutil.Process(), "cpu_affinity"): cpu_cnt = len(psutil.Process().cpu_affinity()) else: cpu_cnt = psutil.cpu_count(logical=False) if cpu_cnt is None: cpu_cnt = psutil.cpu_count(logical=True) _global_values["ncores"] = cpu_cnt _global_values["nnodes"] = 1 _global_values["cpuinfo"] = cpuinfo.get_cpu_info() _global_values["cpu_brand"] = _global_values["cpuinfo"]["brand"] if key is None: return _global_values.copy() else: > return _global_values[key] E KeyError: 'cpu_brand' qcengine/config.py:57: KeyError ________________________________________ test_random_failure_no_retries ________________________________________ failure_engine = FailEngine(name='testing_random_name', scratch=False, thread_safe=True, thread_parallel=False, node_parallel=False, managed_memory=False, extras=None, iter_modes=[], ncalls=1, start_distance=5, equilibrium_distance=4) def test_random_failure_no_retries(failure_engine): failure_engine.iter_modes = ["input_error"] > ret = qcng.compute(failure_engine.get_job(), failure_engine.name, raise_error=False) qcengine/programs/tests/test_programs.py:210: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ qcengine/compute.py:102: in compute return handle_output_metadata(output_data, metadata, raise_error=raise_error, return_dict=return_dict) qcengine/util.py:181: in handle_output_metadata provenance_augments = get_provenance_augments() qcengine/config.py:321: in get_provenance_augments "cpu": get_global("cpu_brand"), _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ key = 'cpu_brand' def get_global(key: Optional[str] = None) -> Union[str, Dict[str, Any]]: import cpuinfo import psutil # TODO (wardlt): Implement a means of getting CPU information from compute nodes on clusters for MPI tasks # The QC code runs on a different node than the node running this Python function, which may have different info global _global_values if _global_values is None: _global_values = {} _global_values["hostname"] = socket.gethostname() _global_values["memory"] = round(psutil.virtual_memory().available / (1024 ** 3), 3) _global_values["username"] = getpass.getuser() # Work through VMs and logical cores. if hasattr(psutil.Process(), "cpu_affinity"): cpu_cnt = len(psutil.Process().cpu_affinity()) else: cpu_cnt = psutil.cpu_count(logical=False) if cpu_cnt is None: cpu_cnt = psutil.cpu_count(logical=True) _global_values["ncores"] = cpu_cnt _global_values["nnodes"] = 1 _global_values["cpuinfo"] = cpuinfo.get_cpu_info() _global_values["cpu_brand"] = _global_values["cpuinfo"]["brand"] if key is None: return _global_values.copy() else: > return _global_values[key] E KeyError: 'cpu_brand' qcengine/config.py:57: KeyError _______________________________________ test_random_failure_with_retries _______________________________________ failure_engine = FailEngine(name='testing_random_name', scratch=False, thread_safe=True, thread_parallel=False, node_parallel=False, managed_memory=False, extras=None, iter_modes=[], ncalls=3, start_distance=5, equilibrium_distance=4) def test_random_failure_with_retries(failure_engine): failure_engine.iter_modes = ["random_error", "random_error", "random_error"] > ret = qcng.compute(failure_engine.get_job(), failure_engine.name, raise_error=False, local_options={"retries": 2}) qcengine/programs/tests/test_programs.py:223: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ qcengine/compute.py:102: in compute return handle_output_metadata(output_data, metadata, raise_error=raise_error, return_dict=return_dict) qcengine/util.py:181: in handle_output_metadata provenance_augments = get_provenance_augments() qcengine/config.py:321: in get_provenance_augments "cpu": get_global("cpu_brand"), _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ key = 'cpu_brand' def get_global(key: Optional[str] = None) -> Union[str, Dict[str, Any]]: import cpuinfo import psutil # TODO (wardlt): Implement a means of getting CPU information from compute nodes on clusters for MPI tasks # The QC code runs on a different node than the node running this Python function, which may have different info global _global_values if _global_values is None: _global_values = {} _global_values["hostname"] = socket.gethostname() _global_values["memory"] = round(psutil.virtual_memory().available / (1024 ** 3), 3) _global_values["username"] = getpass.getuser() # Work through VMs and logical cores. if hasattr(psutil.Process(), "cpu_affinity"): cpu_cnt = len(psutil.Process().cpu_affinity()) else: cpu_cnt = psutil.cpu_count(logical=False) if cpu_cnt is None: cpu_cnt = psutil.cpu_count(logical=True) _global_values["ncores"] = cpu_cnt _global_values["nnodes"] = 1 _global_values["cpuinfo"] = cpuinfo.get_cpu_info() _global_values["cpu_brand"] = _global_values["cpuinfo"]["brand"] if key is None: return _global_values.copy() else: > return _global_values[key] E KeyError: 'cpu_brand' qcengine/config.py:57: KeyError _______________________________________ test_random_failure_with_success _______________________________________ failure_engine = FailEngine(name='testing_random_name', scratch=False, thread_safe=True, thread_parallel=False, node_parallel=False, managed_memory=False, extras=None, iter_modes=[], ncalls=2, start_distance=5, equilibrium_distance=4) def test_random_failure_with_success(failure_engine): failure_engine.iter_modes = ["random_error", "pass"] failure_engine.ncalls = 0 > ret = qcng.compute(failure_engine.get_job(), failure_engine.name, raise_error=False, local_options={"retries": 1}) qcengine/programs/tests/test_programs.py:237: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ qcengine/compute.py:102: in compute return handle_output_metadata(output_data, metadata, raise_error=raise_error, return_dict=return_dict) qcengine/util.py:181: in handle_output_metadata provenance_augments = get_provenance_augments() qcengine/config.py:321: in get_provenance_augments "cpu": get_global("cpu_brand"), _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ key = 'cpu_brand' def get_global(key: Optional[str] = None) -> Union[str, Dict[str, Any]]: import cpuinfo import psutil # TODO (wardlt): Implement a means of getting CPU information from compute nodes on clusters for MPI tasks # The QC code runs on a different node than the node running this Python function, which may have different info global _global_values if _global_values is None: _global_values = {} _global_values["hostname"] = socket.gethostname() _global_values["memory"] = round(psutil.virtual_memory().available / (1024 ** 3), 3) _global_values["username"] = getpass.getuser() # Work through VMs and logical cores. if hasattr(psutil.Process(), "cpu_affinity"): cpu_cnt = len(psutil.Process().cpu_affinity()) else: cpu_cnt = psutil.cpu_count(logical=False) if cpu_cnt is None: cpu_cnt = psutil.cpu_count(logical=True) _global_values["ncores"] = cpu_cnt _global_values["nnodes"] = 1 _global_values["cpuinfo"] = cpuinfo.get_cpu_info() _global_values["cpu_brand"] = _global_values["cpuinfo"]["brand"] if key is None: return _global_values.copy() else: > return _global_values[key] E KeyError: 'cpu_brand' qcengine/config.py:57: KeyError __________________________________________________ test_info ___________________________________________________ def test_info(): """Test for qcengine info""" outputs = [] for arg in cli.info_choices: > output = run_qcengine_cli(["info", arg]) qcengine/tests/test_cli.py:50: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ qcengine/tests/test_cli.py:35: in run_qcengine_cli return subprocess.check_output([sys.executable, "-m", "qcengine"] + args, input=stdin) ../miniconda3/envs/qcengine/lib/python3.8/subprocess.py:411: in check_output return run(*popenargs, stdout=PIPE, timeout=timeout, check=True, _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ input = b'', capture_output = False, timeout = None, check = True popenargs = (['/Users/mwt/software/miniconda3/envs/qcengine/bin/python', '-m', 'qcengine', 'info', 'config'],) kwargs = {'stdin': -1, 'stdout': -1}, process =Additional context