Skip to content

Commit d138a20

Browse files
committed
Paths are set by setup script.
1 parent ed83e5b commit d138a20

7 files changed

+65
-43
lines changed

.gitignore

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
examples
22
intro
33
tests
4-
paths.yaml
4+
autopaths.py

README.md

+20-14
Original file line numberDiff line numberDiff line change
@@ -5,21 +5,27 @@ Goal: Provide tools that make it easy to manage and store QWalk runs.
55

66
# Getting started.
77

8+
Run `setup.py` to fill in the locations of packages you may want to use with autogen, such as Crystal or PySCF.
9+
- without this step autogen will not be able to run any executibles.
10+
811
Check out the intro folder, which constains a set of jupyter notebooks to help you understand how this package works.
12+
Alternative python scripts (which are just python downloads of the notebooks) are also there.
913

1014
Working through all the notebooks should only take ~10 minutes.
1115

12-
# Object definitions
13-
14-
## Level 1: constructing input files and gathering data
15-
16-
* The Writer object has all options to set up a job as member variables, and can construct input files for a run given those input files.
17-
* The Reader object can read the output of a run and report on its completion or lack thereof. This object defines what a successful run is.
18-
* The Runner object executes a set of runs for a given code on a given computer system.
19-
20-
## Level 2: Manager
21-
22-
The Manager object consists of at least one Writer, Reader, and Runner. The Manager owns the directory for the time of its execution, that is, until it says it's done.
23-
A manager may need multiple nextstep() calls before it's done. For example, one might want to run crystal and then properties using a queue to run both.
24-
25-
Calling `nextstep` repeatedly will attempt to finish the calculation, one step at a time.
16+
You can also checkout `tests/simple_test.py` for a more useful template to build scripts from.
17+
18+
# Troubleshooting
19+
20+
- autogen can't find an executible.
21+
- Make sure you've run `setup.py`.
22+
- The notebooks keep saying 'file not found'?
23+
- If you have any error when running the notebook, try restarting the kernel.
24+
Sometimes the current state of the kernel is the problem.
25+
- A manager isn't updating some attributes or is refusing to update some attributes.
26+
- Be careful! This sometimes means you've changed the input file but the old output is still around.
27+
This can lead to bad data if not dealt with carefully!
28+
Check that you didn't change any parameters that affect the accuracy of the calculation.
29+
If you want to force the change, you can delete the manager, and it'll go through with what you say.
30+
To be safe, you should probably remove all the output generated by that manager as well.
31+
`rm ${name}*` where name=[the manager's name].

__init__.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@
1515
"pyscf2qwalk",
1616
"qwalkrunner",
1717
"runner",
18+
"paths",
1819
"submitter",
1920
"trialfunc",
20-
"variance"
21+
"variance",
2122
]

autorunner.py

+11-5
Original file line numberDiff line numberDiff line change
@@ -275,7 +275,6 @@ class PySCFRunnerPBS(RunnerPBS):
275275
def __init__(self,queue='batch',
276276
walltime='12:00:00',
277277
np='allprocs',
278-
ppath=None,
279278
nn=1,
280279
jobname=os.getcwd().split('/')[-1]+'_pyscf',
281280
prefix=None,
@@ -290,8 +289,6 @@ def __init__(self,queue='batch',
290289
self.prefix=prefix
291290
self.postfix=postfix
292291
self.exelines=[]
293-
if ppath is None: self.ppath=[]
294-
else: self.ppath=ppath
295292
if prefix is None: self.prefix=[]
296293
else: self.prefix=prefix
297294
if postfix is None: self.postfix=[]
@@ -327,7 +324,16 @@ def script(self,scriptfile):
327324
return True
328325

329326
#-------------------------------------
330-
def submit(self,jobname=None):
327+
def submit(self,jobname=None,ppath=None):
328+
''' Submit any accumulated tasks.
329+
330+
Args:
331+
jobname (str): name to appear in the queue.
332+
ppath (list): python path needed for the run (default: current path).
333+
'''
334+
335+
if ppath is None: ppath=sys.path
336+
331337
if len(self.exelines)==0:
332338
#print(self.__class__.__name__,": All tasks completed or queued.")
333339
return
@@ -352,7 +358,7 @@ def submit(self,jobname=None):
352358
"#PBS -o %s"%jobout,
353359
"cd ${PBS_O_WORKDIR}",
354360
"export OMP_NUM_THREADS=%d"%(self.nn*self.np),
355-
"export PYTHONPATH=%s"%(':'.join(self.ppath)),
361+
"export PYTHONPATH=%s"%(':'.join(ppath)),
356362
"cwd=`pwd`"
357363
] + self.prefix + self.exelines + self.postfix
358364
qsubfile=jobname+".qsub"

manager.py

+9-9
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import crystal2qmc
2323
import pickle as pkl
2424
import autorunner
25+
from autopaths import paths
2526

2627
from copy import deepcopy
2728

@@ -261,7 +262,7 @@ def nextstep(self):
261262

262263
if status=="not_started":
263264
self.runner.add_command("cp %s INPUT"%self.crysinpfn)
264-
self.runner.add_task("Pcrystal &> %s"%self.crysoutfn)
265+
self.runner.add_task("%s &> %s"%(paths['Pcrystal'],self.crysoutfn))
265266

266267
elif status=="ready_for_analysis":
267268
#This is where we (eventually) do error correction and resubmits
@@ -286,7 +287,7 @@ def nextstep(self):
286287
sh.copy(self.writer.guess_fort,'fort.20')
287288
self.writer.write_crys_input(self.crysinpfn)
288289
sh.copy(self.crysinpfn,'INPUT')
289-
self.runner.add_task("Pcrystal &> %s"%self.crysoutfn)
290+
self.runner.add_task("%s &> %s"%(paths['Pcrystal'],self.crysoutfn))
290291
self.restarts+=1
291292
elif status=='done' and self.lev:
292293
# We used levshift to converge. Now let's restart to be sure.
@@ -302,7 +303,7 @@ def nextstep(self):
302303
sh.copy(self.writer.guess_fort,'fort.20')
303304
self.writer.write_crys_input(self.crysinpfn)
304305
sh.copy(self.crysinpfn,'INPUT')
305-
self.runner.add_task("Pcrystal &> %s"%self.crysoutfn)
306+
self.runner.add_task("%s &> %s"%(paths['Pcrystal'],self.crysoutfn))
306307
self.restarts+=1
307308

308309
# Ready for bundler or else just submit the jobs as needed.
@@ -373,7 +374,7 @@ def export_qwalk(self):
373374
if status=='not_started':
374375
ready=False
375376
self.prunner.add_command("cp %s INPUT"%self.propinpfn)
376-
self.prunner.add_task("Pproperties &> %s"%self.propoutfn)
377+
self.prunner.add_task("%s &> %s"%(paths['Pproperties'],self.propoutfn))
377378

378379
if self.bundle:
379380
self.scriptfile="%s.run"%self.name
@@ -527,7 +528,7 @@ def nextstep(self):
527528
self.scriptfile="%s.run"%self.name
528529
self.bundle_ready=self.runner.script(self.scriptfile,self.driverfn)
529530
else:
530-
qsubfile=self.runner.submit()
531+
qsubfile=self.runner.submit(jobname=self.name,ppath=[paths['pyscf']])
531532

532533
self.completed=self.reader.completed
533534
# Update the file.
@@ -577,7 +578,7 @@ def status(self):
577578
#######################################################################
578579
class QWalkManager:
579580
def __init__(self,writer,reader,runner=None,trialfunc=None,
580-
name='qw_run',path=None,bundle=False,qwalk='~/bin/qwalk'):
581+
name='qw_run',path=None,bundle=False):
581582
''' QWalkManager managers the writing of a QWalk input files, it's running, and keeping track of the results.
582583
Args:
583584
writer (qwalk writer): writer for input.
@@ -606,7 +607,6 @@ def __init__(self,writer,reader,runner=None,trialfunc=None,
606607
self.writer=writer
607608
self.reader=reader
608609
self.trialfunc=trialfunc
609-
self.qwalk=qwalk
610610
if runner is not None: self.runner=runner
611611
else: self.runner=autorunner.RunnerPBS()
612612
self.bundle=bundle
@@ -683,7 +683,7 @@ def nextstep(self):
683683
status=resolve_status(self.runner,self.reader,self.outfile)
684684
print(self.logname,": %s status= %s"%(self.name,status))
685685
if status=="not_started" and self.writer.completed:
686-
exestr="%s %s &> %s"%(self.qwalk,self.infile,self.stdout)
686+
exestr="%s %s &> %s"%(paths['qwalk'],self.infile,self.stdout)
687687
self.runner.add_task(exestr)
688688
print(self.logname,": %s status= submitted"%(self.name))
689689
elif status=="ready_for_analysis":
@@ -694,7 +694,7 @@ def nextstep(self):
694694
self.completed=True
695695
else:
696696
print(self.logname,": %s status= %s, attempting rerun."%(self.name,status))
697-
exestr="%s %s &> %s"%(self.qwalk,self.infile,self.stdout)
697+
exestr="%s %s &> %s"%(paths['qwalk'],self.infile,self.stdout)
698698
self.runner.add_task(exestr)
699699
elif status=='done':
700700
self.completed=True

paths.yaml

-6
This file was deleted.

setup.py

+22-7
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,26 @@
1-
import yaml
1+
import os
22

3-
print("Setting up paths...")
4-
curpaths=yaml.load(open('paths.yaml','r'))
3+
print()
4+
print("Setting up paths.")
5+
print()
6+
print("You'll need to know the location of Crystal, Crystal's properties component, QWalk,")
7+
print("and the PySCF library if you want to use any of them in autogen.")
8+
print("Use absolute paths.")
9+
print()
510

6-
for key in curpaths:
7-
path=input("Enter path for %s: "%key)
11+
curpaths={}
12+
keys=['Pcrystal','Pproperties','qwalk','pyscf']
13+
14+
for key in sorted(keys):
15+
path=input("--Enter path for %s (empty to disable): "%key)
16+
if path=='':
17+
path=None
18+
else:
19+
assert os.path.exists(path),\
20+
"Couldn't find '%s', you should check that it exists, or that it's spelled correctly."%path
821
curpaths[key]=path
922

10-
yaml.dump(curpaths,open('paths.yaml','w'),default_flow_style=False)
11-
print("Done. paths.yaml should now be up-to-date.")
23+
with open('autopaths.py','w') as outf:
24+
outf.write('paths={}'.format(curpaths))
25+
26+
print("Done. autopaths.py should now be up-to-date.")

0 commit comments

Comments
 (0)