Skip to content

Commit cc252db

Browse files
author
Daniel G. A. Smith
committedDec 10, 2019
Lint: Blackens code base
1 parent d698330 commit cc252db

File tree

10 files changed

+111
-72
lines changed

10 files changed

+111
-72
lines changed
 

‎Makefile

+2-2
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ install:
99

1010
.PHONY: format
1111
format:
12-
$(autoflake)
13-
$(isort)
12+
# $(autoflake)
13+
# $(isort)
1414
$(black)
1515

1616
.PHONY: lint

‎qcengine/config.py

+21-12
Original file line numberDiff line numberDiff line change
@@ -71,14 +71,19 @@ class NodeDescriptor(pydantic.BaseModel):
7171
memory_safety_factor: int = 10 # Percentage of memory as a safety factor
7272

7373
# Specifications
74-
ncores: Optional[int] = pydantic.Field(None, description="""Number of cores accessible to each task on this node
74+
ncores: Optional[int] = pydantic.Field(
75+
None,
76+
description="""Number of cores accessible to each task on this node
7577
76-
The default value, ``None``, will allow QCEngine to autodetect the number of cores.""")
78+
The default value, ``None``, will allow QCEngine to autodetect the number of cores.""",
79+
)
7780
jobs_per_node: int = 2
7881
retries: int = 0
7982

8083
# Cluster options
81-
is_batch_node: bool = pydantic.Field(False, help="""Whether the node running QCEngine is a batch node
84+
is_batch_node: bool = pydantic.Field(
85+
False,
86+
help="""Whether the node running QCEngine is a batch node
8287
8388
Some clusters are configured such that tasks are launched from a special "batch" or "MOM" onto the compute nodes.
8489
The compute nodes on such clusters often have a different CPU architecture than the batch nodes and
@@ -89,9 +94,11 @@ class NodeDescriptor(pydantic.BaseModel):
8994
9095
``is_batch_node`` is used when creating the task configuration as a means of determining whether
9196
``mpiexec_command`` must always be used even for serial jobs (e.g., getting the version number)
92-
""")
97+
""",
98+
)
9399
mpiexec_command: Optional[str] = pydantic.Field(
94-
None, description="""Invocation for launching node-parallel tasks with MPI
100+
None,
101+
description="""Invocation for launching node-parallel tasks with MPI
95102
96103
The invocation need not specify the number of nodes, tasks, or cores per node.
97104
Information about the task configuration will be added to the command by use of
@@ -112,7 +119,7 @@ class NodeDescriptor(pydantic.BaseModel):
112119
``aprun -n {total_ranks} -N {ranks_per_node} -d {cores_per_rank} -j 1``.
113120
The appropriate number of ranks per node will be determined based on the number of
114121
cores per node and the number of cores per rank.
115-
"""
122+
""",
116123
)
117124

118125
def __init__(self, **data: Dict[str, Any]):
@@ -121,10 +128,10 @@ def __init__(self, **data: Dict[str, Any]):
121128

122129
if self.mpiexec_command is not None:
123130
# Ensure that the mpiexec_command contains necessary information
124-
if not ('{total_ranks}' in self.mpiexec_command or '{nnodes}' in self.mpiexec_command):
125-
raise ValueError('mpiexec_command must contain either {total_ranks} or {nnodes}')
126-
if '{ranks_per_node}' not in self.mpiexec_command:
127-
raise ValueError('mpiexec_command must explicitly state the number of ranks per node')
131+
if not ("{total_ranks}" in self.mpiexec_command or "{nnodes}" in self.mpiexec_command):
132+
raise ValueError("mpiexec_command must contain either {total_ranks} or {nnodes}")
133+
if "{ranks_per_node}" not in self.mpiexec_command:
134+
raise ValueError("mpiexec_command must explicitly state the number of ranks per node")
128135

129136
class Config:
130137
extra = "forbid"
@@ -301,8 +308,10 @@ def get_config(*, hostname: Optional[str] = None, local_options: Dict[str, Any]
301308

302309
# Make sure mpirun command is defined if needed
303310
if config["use_mpiexec"] and config["mpiexec_command"] is None:
304-
raise ValueError("You need to define the mpiexec command for this node. "
305-
"See: https://qcengine.readthedocs.io/en/stable/environment.html")
311+
raise ValueError(
312+
"You need to define the mpiexec command for this node. "
313+
"See: https://qcengine.readthedocs.io/en/stable/environment.html"
314+
)
306315

307316
return TaskConfig(**config)
308317

‎qcengine/programs/entos.py

+5-5
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,7 @@ def build_input(
202202
energy_keywords_from_input_model = {
203203
"dft": {"xc": input_model.model.method.upper(), **scf_keywords_from_input_model},
204204
"hf": {**scf_keywords_from_input_model},
205-
"xtb": {"charge": input_model.molecule.molecular_charge,},
205+
"xtb": {"charge": input_model.molecule.molecular_charge},
206206
}
207207

208208
# Resolve keywords (extra options) for the energy command
@@ -222,22 +222,22 @@ def build_input(
222222
**structure,
223223
**energy_keywords_from_input_model[energy_command],
224224
**energy_keywords_extra,
225-
},
225+
}
226226
}
227227
# Create the input dictionary for a gradient call
228228
elif input_model.driver == "gradient":
229229
input_dict = {
230230
"gradient": {
231231
**structure,
232-
energy_command: {**energy_keywords_from_input_model[energy_command], **energy_keywords_extra,},
233-
},
232+
energy_command: {**energy_keywords_from_input_model[energy_command], **energy_keywords_extra},
233+
}
234234
}
235235
elif input_model.driver == "hessian":
236236
input_dict = {
237237
"hessian": {
238238
**structure,
239239
energy_command: {**energy_keywords_from_input_model[energy_command], **energy_keywords_extra},
240-
},
240+
}
241241
}
242242
else:
243243
raise NotImplementedError(f"Driver {input_model.driver} not implemented for entos.")

‎qcengine/programs/nwchem/germinate.py

+1-2
Original file line numberDiff line numberDiff line change
@@ -170,8 +170,7 @@ def muster_modelchem(method: str, derint: int, use_tce: bool) -> Tuple[str, Dict
170170

171171
elif method == "tce":
172172
raise InputError(
173-
f"Do not specify TCE as a method. Instead specify the desired method "
174-
f'as a keyword and "qc_module=True".'
173+
f"Do not specify TCE as a method. Instead specify the desired method " f'as a keyword and "qc_module=True".'
175174
)
176175

177176
elif method in _xc_functionals:

‎qcengine/programs/nwchem/harvester.py

+28-22
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ def harvest_outfile_pass(outtext):
5757
version = ""
5858
error = "" # TODO (wardlt): The error string is never used.
5959

60-
NUMBER = r'(?x:' + regex.NUMBER + ')'
60+
NUMBER = r"(?x:" + regex.NUMBER + ")"
6161
# fmt: off
6262

6363
# Process version
@@ -590,17 +590,21 @@ def harvest_outfile_pass(outtext):
590590
psivar['NWCHEM ERROR CODE'] = mobj.group(1)
591591
# TODO process errors into error var
592592

593+
# fmt: on
594+
593595
# Get the size of the basis sets, etc
594-
mobj = re.search(r'No. of atoms\s+:\s+(\d+)', outtext, re.MULTILINE)
596+
mobj = re.search(r"No. of atoms\s+:\s+(\d+)", outtext, re.MULTILINE)
595597
if mobj:
596598
psivar["N ATOMS"] = mobj.group(1)
597-
mobj = re.search(r"No. of electrons\s+:\s+(\d+)\s+Alpha electrons\s+:\s+(\d+)\s+Beta electrons\s+:\s+(\d+)",
598-
outtext, re.MULTILINE)
599+
mobj = re.search(
600+
r"No. of electrons\s+:\s+(\d+)\s+Alpha electrons\s+:\s+(\d+)\s+Beta electrons\s+:\s+(\d+)",
601+
outtext,
602+
re.MULTILINE,
603+
)
599604
if mobj:
600605
psivar["N ALPHA ELECTRONS"] = mobj.group(2)
601606
psivar["N BETA ELECTRONS"] = mobj.group(3)
602-
mobj = re.search(r"AO basis - number of functions:\s+(\d+)\s+number of shells:\s+(\d+)",
603-
outtext, re.MULTILINE)
607+
mobj = re.search(r"AO basis - number of functions:\s+(\d+)\s+number of shells:\s+(\d+)", outtext, re.MULTILINE)
604608
if mobj:
605609
psivar["N MO"] = mobj.group(2)
606610
psivar["N BASIS"] = mobj.group(1)
@@ -670,28 +674,30 @@ def extract_formatted_properties(psivars: PreservingDict) -> AtomicResultPropert
670674
output = dict()
671675

672676
# Extract the Calc Info
673-
output.update({
674-
'calcinfo_nbasis': psivars.get('N BASIS', None),
675-
'calcinfo_nmo': psivars.get('N MO', None),
676-
'calcinfo_natom': psivars.get('N ATOMS', None),
677-
'calcinfo_nalpha': psivars.get('N ALPHA ELECTRONS', None),
678-
'calcinfo_nbeta': psivars.get('N BETA ELECTRONS', None)
679-
})
677+
output.update(
678+
{
679+
"calcinfo_nbasis": psivars.get("N BASIS", None),
680+
"calcinfo_nmo": psivars.get("N MO", None),
681+
"calcinfo_natom": psivars.get("N ATOMS", None),
682+
"calcinfo_nalpha": psivars.get("N ALPHA ELECTRONS", None),
683+
"calcinfo_nbeta": psivars.get("N BETA ELECTRONS", None),
684+
}
685+
)
680686

681687
# Get the "canonical" properties
682-
output['return_energy'] = psivars['CURRENT ENERGY']
683-
output['nuclear_repulsion_energy'] = psivars['NUCLEAR REPULSION ENERGY']
688+
output["return_energy"] = psivars["CURRENT ENERGY"]
689+
output["nuclear_repulsion_energy"] = psivars["NUCLEAR REPULSION ENERGY"]
684690

685691
# Get the SCF properties
686-
output['scf_total_energy'] = psivars.get('HF TOTAL ENERGY', None)
687-
output['scf_one_electron_energy'] = psivars.get('ONE-ELECTRON ENERGY', None)
688-
output['scf_two_electron_energy'] = psivars.get('ONE-ELECTRON ENERGY', None)
692+
output["scf_total_energy"] = psivars.get("HF TOTAL ENERGY", None)
693+
output["scf_one_electron_energy"] = psivars.get("ONE-ELECTRON ENERGY", None)
694+
output["scf_two_electron_energy"] = psivars.get("ONE-ELECTRON ENERGY", None)
689695

690696
# Get the MP2 properties
691-
output['mp2_total_correlation_energy'] = psivars.get('MP2 CORRELATION ENERGY', None)
692-
output['mp2_total_energy'] = psivars.get('MP2 TOTAL ENERGY', None)
693-
output['mp2_same_spin_correlation_energy'] = psivars.get('MP2 SAME-SPIN CORRELATION ENERGY', None)
694-
output['mp2_opposite_spin_correlation_energy'] = psivars.get('MP2 OPPOSITE-SPIN CORRELATION ENERGY', None)
697+
output["mp2_total_correlation_energy"] = psivars.get("MP2 CORRELATION ENERGY", None)
698+
output["mp2_total_energy"] = psivars.get("MP2 TOTAL ENERGY", None)
699+
output["mp2_same_spin_correlation_energy"] = psivars.get("MP2 SAME-SPIN CORRELATION ENERGY", None)
700+
output["mp2_opposite_spin_correlation_energy"] = psivars.get("MP2 OPPOSITE-SPIN CORRELATION ENERGY", None)
695701
return AtomicResultProperties(**output)
696702

697703

‎qcengine/programs/nwchem/runner.py

+1-2
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,7 @@ def get_version(self) -> str:
7373
command.append("v.nw")
7474

7575
if which_prog not in self.version_cache:
76-
success, output = execute(command, {"v.nw": ""},
77-
scratch_directory=config.scratch_directory)
76+
success, output = execute(command, {"v.nw": ""}, scratch_directory=config.scratch_directory)
7877

7978
if success:
8079
for line in output["stdout"].splitlines():

‎qcengine/programs/qchem.py

+5-1
Original file line numberDiff line numberDiff line change
@@ -374,7 +374,11 @@ def parse_logfile(self, outfiles: Dict[str, str]) -> AtomicResult:
374374
jobtype = keywords.pop("jobtype")
375375
else:
376376
jobtype = "sp"
377-
_jobtype_to_driver = {"sp": "energy", "force": "gradient", "freq": "hessian"} # optimization intentionally not supported
377+
_jobtype_to_driver = {
378+
"sp": "energy",
379+
"force": "gradient",
380+
"freq": "hessian",
381+
} # optimization intentionally not supported
378382
try:
379383
input_dict["driver"] = _jobtype_to_driver[jobtype]
380384
except KeyError:

‎qcengine/tests/test_config.py

+32-15
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ def opt_state_basic():
8585
"jobs_per_node": 1,
8686
"mpiexec_command": "mpirun -n {total_ranks} -N {ranks_per_node}",
8787
"ncores": 24,
88-
"memory": 240
88+
"memory": 240,
8989
},
9090
{
9191
"name": "default",
@@ -168,24 +168,42 @@ def test_config_local_nnodes(opt_state_basic):
168168
# Give a warning that mentions that mpirun is needed if you define a multi-node task
169169
with pytest.raises(ValueError) as exc:
170170
qcng.config.get_config(hostname="something", local_options={"nnodes": 10})
171-
assert 'https://qcengine.readthedocs.io/en/stable/environment.html' in str(exc.value)
171+
assert "https://qcengine.readthedocs.io/en/stable/environment.html" in str(exc.value)
172172

173173
# Test with an MPI run command
174-
local_options = {"nnodes": 4,
175-
"mpiexec_command": "mpirun -n {total_ranks} -N {ranks_per_node} --cpus-per-slot {cores_per_rank}"}
174+
local_options = {
175+
"nnodes": 4,
176+
"mpiexec_command": "mpirun -n {total_ranks} -N {ranks_per_node} --cpus-per-slot {cores_per_rank}",
177+
}
176178
config = qcng.config.get_config(hostname="something", local_options=local_options)
177179
assert config.use_mpiexec
178-
assert config.mpiexec_command.startswith('mpirun')
179-
assert create_mpi_invocation('hello_world', config) == ['mpirun', '-n', '20', '-N', '5', '--cpus-per-slot', '1',
180-
'hello_world']
180+
assert config.mpiexec_command.startswith("mpirun")
181+
assert create_mpi_invocation("hello_world", config) == [
182+
"mpirun",
183+
"-n",
184+
"20",
185+
"-N",
186+
"5",
187+
"--cpus-per-slot",
188+
"1",
189+
"hello_world",
190+
]
181191

182192
# Change the number of cores per rank
183193
local_options["cores_per_rank"] = 2
184-
config = qcng.config.get_config(hostname='something', local_options=local_options)
194+
config = qcng.config.get_config(hostname="something", local_options=local_options)
185195
assert config.use_mpiexec
186-
assert config.mpiexec_command.startswith('mpirun')
187-
assert create_mpi_invocation('hello_world', config) == ['mpirun', '-n', '20', '-N', '2', '--cpus-per-slot', '2',
188-
'hello_world']
196+
assert config.mpiexec_command.startswith("mpirun")
197+
assert create_mpi_invocation("hello_world", config) == [
198+
"mpirun",
199+
"-n",
200+
"20",
201+
"-N",
202+
"2",
203+
"--cpus-per-slot",
204+
"2",
205+
"hello_world",
206+
]
189207

190208

191209
def test_config_validation(opt_state_basic):
@@ -204,7 +222,7 @@ def test_batch_node(opt_state_basic):
204222
assert config.ncores == 24
205223
assert config.nnodes == 1
206224

207-
config = qcng.config.get_config(hostname="bn1", local_options={'nnodes': 2})
225+
config = qcng.config.get_config(hostname="bn1", local_options={"nnodes": 2})
208226
assert config.use_mpiexec
209227
assert config.ncores == 24
210228
assert config.nnodes == 2
@@ -214,9 +232,8 @@ def test_mpirun_command_errors():
214232
# Checks for ranks_per_node
215233
with pytest.raises(ValueError) as exc:
216234
NodeDescriptor(name="something", hostname_pattern="*", mpiexec_command="mpirun -n {total_ranks}")
217-
assert 'must explicitly state' in str(exc.value)
235+
assert "must explicitly state" in str(exc.value)
218236

219237
with pytest.raises(ValueError) as exc:
220238
NodeDescriptor(name="something", hostname_pattern="*", mpiexec_command="mpirun -N {ranks_per_node}")
221-
assert 'must contain either' in str(exc.value)
222-
239+
assert "must contain either" in str(exc.value)

‎qcengine/tests/test_utils.py

+7-7
Original file line numberDiff line numberDiff line change
@@ -79,13 +79,13 @@ def test_disk_files():
7979

8080
def test_popen_tee_output(capsys):
8181
# Test without passing
82-
with util.popen(['echo', 'hello']) as proc:
83-
proc['proc'].wait()
84-
assert proc['stdout'].strip() == 'hello'
82+
with util.popen(["echo", "hello"]) as proc:
83+
proc["proc"].wait()
84+
assert proc["stdout"].strip() == "hello"
8585

8686
# Test with passing
87-
with util.popen(['echo', 'hello'], pass_output_forward=True) as proc:
88-
proc['proc'].wait()
89-
assert proc['stdout'] == 'hello\n'
87+
with util.popen(["echo", "hello"], pass_output_forward=True) as proc:
88+
proc["proc"].wait()
89+
assert proc["stdout"] == "hello\n"
9090
captured = capsys.readouterr()
91-
assert captured.out == 'hello\n'
91+
assert captured.out == "hello\n"

‎qcengine/util.py

+9-4
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ def create_mpi_invocation(executable: str, task_config: TaskConfig) -> List[str]
4444
nnodes=task_config.nnodes,
4545
ranks_per_node=task_config.ncores // task_config.cores_per_rank,
4646
total_ranks=task_config.nnodes * task_config.ncores,
47-
cores_per_rank=task_config.cores_per_rank
47+
cores_per_rank=task_config.cores_per_rank,
4848
)
4949
command = mpirun_str.split()
5050

@@ -218,8 +218,12 @@ def terminate_process(proc: Any, timeout: int = 15) -> None:
218218

219219

220220
@contextmanager
221-
def popen(args: List[str], append_prefix: bool = False, popen_kwargs: Optional[Dict[str, Any]] = None,
222-
pass_output_forward: bool = False) -> Dict[str, Any]:
221+
def popen(
222+
args: List[str],
223+
append_prefix: bool = False,
224+
popen_kwargs: Optional[Dict[str, Any]] = None,
225+
pass_output_forward: bool = False,
226+
) -> Dict[str, Any]:
223227
"""
224228
Opens a background task
225229
@@ -287,10 +291,11 @@ def popen(args: List[str], append_prefix: bool = False, popen_kwargs: Optional[D
287291
# from the buffers to ensure that they do not fill.
288292
#
289293
def read_from_buffer(buffer: BinaryIO, storage: io.BytesIO, sysio: TextIO):
290-
for r in iter(partial(buffer.read, 1024), b''):
294+
for r in iter(partial(buffer.read, 1024), b""):
291295
storage.write(r)
292296
if pass_output_forward:
293297
sysio.write(r.decode())
298+
294299
stdout_reader = Thread(target=read_from_buffer, args=(ret["proc"].stdout, stdout, sys.stdout))
295300
stdout_reader.start()
296301
stderr_reader = Thread(target=read_from_buffer, args=(ret["proc"].stderr, stderr, sys.stderr))

0 commit comments

Comments
 (0)
Please sign in to comment.