From 2828381b3cd0237b158e421a078e49dfe7b69d7d Mon Sep 17 00:00:00 2001 From: Jaron Krogel Date: Thu, 13 Nov 2014 20:33:08 +0000 Subject: [PATCH] ability to alter environment per job git-svn-id: https://subversion.assembla.com/svn/qmcdev/trunk@6401 e5b18d87-469d-4833-9cc0-8cdfa06e9491 --- nexus/library/machines.py | 104 +++++--- nexus/library/pseudopotential.py | 172 ++++++++++-- nexus/library/vasp.py | 145 +++++++++- nexus/library/vasp_analyzer.py | 439 +++++++++++++++++++++++++++++-- 4 files changed, 767 insertions(+), 93 deletions(-) diff --git a/nexus/library/machines.py b/nexus/library/machines.py index 547af3929..2a01b4dde 100644 --- a/nexus/library/machines.py +++ b/nexus/library/machines.py @@ -132,6 +132,9 @@ class Job(Pobj): app_props = None, app = None, env = None, + user_env = True, + presub = '', + postsub = '', outfile = None, errfile = None, mode = None, @@ -170,6 +173,9 @@ class Job(Pobj): self.app_props = app_props self.outfile = outfile self.errfile = errfile + self.user_env = user_env + self.presub = presub + self.postsub = postsub self.name = name self.queue = queue self.bundled_jobs= bundled_jobs @@ -862,7 +868,13 @@ class Workstation(Machine): def submit_job(self,job): pad = self.enter(job.directory,msg=job.simid) command = 'export OMP_NUM_THREADS='+str(job.threads)+'\n' + if len(job.presub)>0: + command += job.presub+'\n' + #end if command += job.run_command(self.app_launcher) + if len(job.postsub)>0: + command += job.postsub+'\n' + #end if command = ('\n'+command).replace('\n','\n '+pad) job.status = job.states.running process = obj() @@ -1390,12 +1402,6 @@ class Supercomputer(Machine): os.system(command) #end def remove_job - - def set_submission_commands(self,job): - self.pre_submission_commands = 'date\n' - self.post_submission_commands= '' - #end def set_submission_commands - def setup_environment(self,job): env = '' @@ -1412,13 +1418,16 @@ class Supercomputer(Machine): job.subfile = job.name+'.'+self.sub_launcher+'.in' env = self.setup_environment(job) command = job.run_command(self.app_launcher) - self.set_submission_commands(job) c = self.write_job_header(job)+'\n' - c+=self.pre_submission_commands+'\n' + if len(job.presub)>0: + c+=job.presub+'\n' + #end if c+=env c+=command+'\n' - c+=self.post_submission_commands+'\n' + if len(job.postsub)>0: + c+=job.postsub+'\n' + #end if filepath = os.path.join(job.directory,job.subfile) fobj = open(filepath,'w') @@ -1479,8 +1488,10 @@ class Kraken(Supercomputer): c+='#PBS -l size='+str(job.tot_cores)+'\n' c+='#PBS -o '+job.outfile+'\n' c+='#PBS -e '+job.errfile+'\n' - c+='''#PBS -V - + if job.user_env: + c+='#PBS -V\n' + #end if + c+=''' cd $PBS_O_WORKDIR export MPICH_PTL_SEND_CREDITS=-1 export MPICH_MAX_SHORT_MSG_SIZE=1024 @@ -1518,7 +1529,9 @@ class Jaguar(Supercomputer): c+='#PBS -l gres=widow2%widow3\n' c+='#PBS -o '+job.outfile+'\n' c+='#PBS -e '+job.errfile+'\n' - #c+='#PBS -V\n' + if job.user_env: + c+='#PBS -V\n' + #end if c+=''' echo $PBS_O_WORKDIR cd $PBS_O_WORKDIR @@ -1555,8 +1568,10 @@ class Taub(Supercomputer): c+='#PBS -l walltime='+job.pbs_walltime()+'\n' c+='#PBS -e '+job.errfile+'\n' c+='#PBS -o '+job.outfile+'\n' - c+='''#PBS -V - + if job.user_env: + c+='#PBS -V\n' + #end if + c+=''' cd ${PBS_O_WORKDIR} export MPICH_PTL_SEND_CREDITS=-1 @@ -1618,8 +1633,10 @@ class OIC5(Supercomputer): c+='#PBS -W x=\"NACCESSPOLICY:SINGLEJOB\"\n' c+='#PBS -o '+job.outfile+'\n' c+='#PBS -e '+job.errfile+'\n' - c+='''#PBS -V - + if job.user_env: + c+='#PBS -V\n' + #end if + c+=''' echo $PBS_O_WORKDIR cd $PBS_O_WORKDIR ''' @@ -1645,9 +1662,7 @@ cd $PBS_O_WORKDIR -class Edison(Supercomputer): - - name = 'edison' +class NerscMachine(Supercomputer): batch_capable = True def process_job_extra(self,job): @@ -1667,7 +1682,6 @@ class Edison(Supercomputer): #end if #end def process_job_extra - def write_job_header(self,job): if job.queue is None: job.queue = 'regular' @@ -1680,30 +1694,25 @@ class Edison(Supercomputer): c+='#PBS -l mppwidth={0}\n'.format(job.tot_cores) c+='#PBS -o '+job.outfile+'\n' c+='#PBS -e '+job.errfile+'\n' - c+='''#PBS -V - + if job.user_env: + c+='#PBS -V\n' + #end if + c+=''' echo $PBS_O_WORKDIR cd $PBS_O_WORKDIR ''' return c #end def write_job_header +#end class NerscMachine - def read_process_id(self,output): - pid = None - lines = output.splitlines() - for line in lines: - if 'edison' in line: - spid = line.split('.')[0] - if spid.isdigit(): - pid = int(spid) - #end if - #end if - #end for - return pid - #end def read_process_id +class Edison(NerscMachine): + name = 'edison' #end class Edison +class Hopper(NerscMachine): + name = 'hopper' +#end class Hopper @@ -1720,8 +1729,10 @@ class BlueWatersXK(Supercomputer): c+='#PBS -l nodes={0}:ppn={1}:xk\n'.format(job.nodes,job.ppn) c+='#PBS -o '+job.outfile+'\n' c+='#PBS -e '+job.errfile+'\n' - c+='''#PBS -V - + if job.user_env: + c+='#PBS -V\n' + #end if + c+=''' echo $PBS_O_WORKDIR cd $PBS_O_WORKDIR ''' @@ -1745,8 +1756,10 @@ class BlueWatersXE(Supercomputer): c+='#PBS -l nodes={0}:ppn={1}:xe\n'.format(job.nodes,job.ppn) c+='#PBS -o '+job.outfile+'\n' c+='#PBS -e '+job.errfile+'\n' - c+='''#PBS -V - + if job.user_env: + c+='#PBS -V\n' + #end if + c+=''' echo $PBS_O_WORKDIR cd $PBS_O_WORKDIR ''' @@ -1777,7 +1790,9 @@ class Titan(Supercomputer): c+='#PBS -l nodes={0}\n'.format(job.nodes) #c+='#PBS -l gres=widow3\n' c+='#PBS -l gres=atlas1\n' - c+='#PBS -V\n' + if job.user_env: + c+='#PBS -V\n' + #end if c+=''' echo $PBS_O_WORKDIR cd $PBS_O_WORKDIR @@ -1817,7 +1832,9 @@ class EOS(Supercomputer): c+='#PBS -l walltime={0}\n'.format(job.pbs_walltime()) c+='#PBS -l nodes={0}\n'.format(job.nodes) c+='#PBS -l gres=atlas1\n' - c+='#PBS -V\n' + if job.user_env: + c+='#PBS -V\n' + #end if c+=''' echo $PBS_O_WORKDIR cd $PBS_O_WORKDIR @@ -1907,7 +1924,9 @@ class Lonestar(Supercomputer): # Lonestar contribution from Paul Young c+='#$ -l h_rt={0}\n'.format(job.pbs_walltime()) c+='#$ -pe 12way {0}\n'.format(job.nodes*12) c+='#$ -cwd\n' - c+='#$ -V\n' + if job.user_env: + c+='#$ -V\n' + #end if return c #end def write_job_header @@ -2054,6 +2073,7 @@ Jaguar( 18688, 2, 8, 32, 100, 'aprun', 'qsub', 'qstat', 'q Kraken( 9408, 2, 6, 16, 100, 'aprun', 'qsub', 'qstat', 'qdel') Taub( 400, 2, 6, 24, 50, 'mpirun', 'qsub', 'qstat', 'qdel') OIC5( 28, 2, 16, 128, 1000, 'mpirun', 'qsub', 'qstat', 'qdel') +Hopper( 6384, 2, 12, 64, 1000, 'aprun', 'qsub', 'qstat', 'qdel') Edison( 664, 2, 8, 64, 100, 'aprun', 'qsub', 'qstat', 'qdel') BlueWatersXK( 3072, 1, 16, 32, 100, 'aprun', 'qsub', 'qstat', 'qdel') BlueWatersXE(22640, 2, 16, 64, 100, 'aprun', 'qsub', 'qstat', 'qdel') diff --git a/nexus/library/pseudopotential.py b/nexus/library/pseudopotential.py index 4821c265c..f9c8d471b 100644 --- a/nexus/library/pseudopotential.py +++ b/nexus/library/pseudopotential.py @@ -281,6 +281,8 @@ class SemilocalPP(Pseudopotential): numeric = False interpolatable = True + formats = ['qmcpack'] + def __init__(self,filepath=None,format=None,name=None,src=None): self.name = name self.rcut = None @@ -327,7 +329,31 @@ class SemilocalPP(Pseudopotential): return self.channels[l] #end def get_channel + + def remove_channel(self,l): + if l in self.channels: + del self.channels[l] + if self.local==l: + lmax = -1 + for lt in self.channels.keys(): + li = self.l_int_from_text(lt) + if li>lmax: + lmax = li + self.local = lt + #end if + #end for + self.lmax = lmax + #end if + #end if + #end def remove_channel + + + def l_int_from_text(self,ltext): + lint = 'spdfgh'.find(ltext) + return lint + #end def l_int_from_text + def evaluate(self,r=None,l=None,rpow=0,with_local=False): if self.numeric and not self.interpolatable: r = None @@ -685,21 +711,48 @@ class GFit(DevBase): class GaussianPP(SemilocalPP): requires_format = True - formats = 'gaussian gamess'.split() + formats = SemilocalPP.formats + 'gaussian gamess'.split() + + @staticmethod + def process_float(s): + return float(s.replace('D','e').replace('d','e')) + #end def process_float + + def __init__(self,filepath=None,format=None,name=None,src=None): + self.basis = None + SemilocalPP.__init__(self,filepath,format,name,src) + #end def __init__ def read_text(self,text,format=None): rawlines = text.splitlines() - lines = [] + sections = [] + last_empty = True for rline in rawlines: line = rline.strip() if (not line.startswith('!')) and (not line.startswith('#')) and len(line)>0: + if last_empty: + lines = [] + sections.append(lines) + #end if lines.append(line) + last_empty = False + else: + last_empty = True #end if #end for + del lines + if len(sections)==2: + basis_lines = sections[0] + lines = sections[1] + else: + basis_lines = None + lines = sections[0] + #end if format=format.lower() channels = [] + basis = None if format=='gamess': i=0 name,type,Zcore,lmax = lines[i].split(); i+=1 @@ -715,6 +768,24 @@ class GaussianPP(SemilocalPP): #end for channels.append(terms) #end while + if basis_lines!=None: + i=1 + basis = obj() + while i2: + if line[1]=='s': + ns = int(line.split()[2]) + spin = obj() + bands[ns] = spin + elif line[1]=='k': + tokens = line.split() + nk = int(tokens[1]) + kp = array(tokens[3:],dtype=float) + kpoint = obj(kpoint=kp,energies=[],occupations=[]) + spin[nk]=kpoint + elif line[2]=='b': + None + else: + bnum,energy,occ = line.split() + kpoint.energies.append(float(energy)) + kpoint.occupations.append(float(occ)) + #end if + last_empty = False + else: + if last_empty: + break + #end if + last_empty = True + #end if + n+=1 + #end for + vlines.advance(n) + #end if + for ns,spin in bands.iteritems(): + for nk,kpoint in spin.iteritems(): + kpoint.energies = array(kpoint.energies,dtype=float) + kpoint.occupations = array(kpoint.occupations,dtype=float) + #end for + #end for + odata.bands = bands +#end def read_outcar_bands + + +def read_outcar_charge_mag(vlines,odata,token): + ion = obj(s=[],p=[],d=[],tot=[]) + total = obj() + vlines.advance_token(token) + vlines.advance(4) + prev_end = False + n=0 + for line in vlines.remainder(): + n+=1 + if prev_end: + break + #end if + if line[0]=='-': + prev_end = True + else: + vals = array(line.split()[1:],dtype=float) + ion.s.append(vals[0]) + ion.p.append(vals[1]) + ion.d.append(vals[2]) + ion.tot.append(vals[3]) + #end if + #end for + for channel,vals in ion.iteritems(): + ion[channel] = array(vals,dtype=float) + #end for + vlines.advance(n) + vals = array(line.split()[1:],dtype=float) + total.s = vals[0] + total.p = vals[1] + total.d = vals[2] + total.tot = vals[3] + return ion,total +#end def read_outcar_charge_mag + + +def read_outcar_total_charge(vlines,odata): + ion,total = read_outcar_charge_mag(vlines,odata,'total charge ') # trailing space is important + odata.ion_charge = ion + odata.total_charge = total +#end def read_outcar_total_charge + + +def read_outcar_magnetization(vlines,odata): + ion,total = read_outcar_charge_mag(vlines,odata,'magnetization') + odata.ion_magnetization = ion + odata.total_magnetization = total +#end def read_outcar_magnetization + + +def read_outcar_stress(vlines,odata): + vlines.advance_token('FORCE on cell') + line = vlines.advance_line(1) + dirs = line.split()[1:] + st = array(vlines.advance_token('Total').split()[1:],dtype=float) + st_kb = array(vlines.advance_line(1).split()[2:],dtype=float) + pressure = float(vlines.advance_line(1).split()[3]) + stress = obj() + stress_kb = obj() + for i in range(len(dirs)): + d = dirs[i].lower() + stress[d] = st[i] + stress_kb[d] = st_kb[i] + #end for + odata.stress = stress + odata.stress_kb = stress_kb + odata.pressure = pressure +#end def read_outcar_stress + + +def read_outcar_cell(vlines,odata): + vlines.advance_token('VOLUME and BASIS') + volume = float(vlines.advance_line(3).split()[-1]) + a1 = vlines.advance_line(2).split()[0:3] + a2 = vlines.advance_line(1).split()[0:3] + a3 = vlines.advance_line(1).split()[0:3] + lattice_vectors = array([a1,a2,a3],dtype=float) + odata.volume = volume + odata.lattice_vectors = lattice_vectors +#end def read_outcar_cell + + +def read_outcar_position_force(vlines,odata): + position = [] + force = [] + vlines.advance_token('POSITION') + vlines.advance(2) + prev_end = False + for line in vlines.remainder(): + if prev_end: + break + #end if + if line[1]=='-': + prev_end = True + else: + tokens = line.split() + position.append(tokens[0:3]) + force.append(tokens[3:6]) + #end if + #end for + total_drift = line.split()[2:5] + odata.position = array(position,dtype=float) + odata.force = array(force,dtype=float) + odata.total_drift = array(total_drift,dtype=float) +#end def read_outcar_position_force + + +def read_outcar_accounting(vlines,odata): + time = obj() + memory = obj() + vlines.advance_token('General timing and accounting') + vlines.advance(2) + time.cpu = float(vlines.advance_line(1).split()[-1]) + time.user = float(vlines.advance_line(1).split()[-1]) + time.system = float(vlines.advance_line(1).split()[-1]) + time.elapsed = float(vlines.advance_line(1).split()[-1]) + vlines.advance(1) + memory.maximum = float(vlines.advance_line(1).split()[-1]) + memory.average = float(vlines.advance_line(1).split()[-1]) + odata.time = time + odata.memory = memory +#end def read_outcar_accounting + + + + +class OutcarData(DevBase): + any_functions = [ + ('header_values' , read_outcar_header_values ), + ] + elast_functions = [ + ('core_potentials' , read_outcar_core_potentials), + ('fermi_energy' , read_outcar_fermi_energy ), + ('bands' , read_outcar_bands ), + ('total_charge' , read_outcar_total_charge ), + ('magnetization' , read_outcar_magnetization ), + ('stress' , read_outcar_stress ), + ('cell' , read_outcar_cell ), + ('position_force' , read_outcar_position_force ), + ] + ilast_functions = [ + ('accounting' , read_outcar_accounting ), + ] + + read_outcar_functions = any_functions + elast_functions + ilast_functions + + def __init__(self,filepath=None,lines=None): + if filepath!=None: + if not os.path.exists(filepath): + self.error('file {0} does not exist'.format(filepath)) + #end if + f = open(filepath,'r') + lines = f.read().splitlines() + f.close() + #end if + self.vlines = VaspLines(lines) + #end def __init__ + + + def read(self,ilast=False,elast=False,all=True): + ilast |= all + elast |= all + vlines = self.vlines + del self.vlines + read_functions = [] + read_functions.extend(self.any_functions) + if elast: + read_functions.extend(self.elast_functions) + if ilast: + read_functions.extend(self.ilast_functions) + #end if + #end if + for quantity,read_function in read_functions: + try: + read_function(vlines,self) + except: + None + #end try + #end for + #end def read +#end class OutcarData + + + + +# main analyzer class + class VaspAnalyzer(SimulationAnalyzer): def __init__(self,arg0=None,xml=False,analyze=False): - self.info = obj(xml=xml) - prefix = None + path = None + prefix = None + incar = None + outcar = None + xmlfile = None if isinstance(arg0,Simulation): sim = arg0 - infile = sim.infile + file = sim.infile path = sim.locdir elif arg0!=None: - path,infile = os.path.split(arg0) - if infile=='': - infile = None - #end if - if infile!=None: - if not infile.endswith('INCAR'): - self.error('please provide the path to an INCAR file') - #end if - prefix = infile.replace('INCAR','').strip() - if prefix=='': - prefix=None - #end if - #end if + path,file = os.path.split(arg0) else: - self.info.xml = False - return + file = '' + xml = False #end if - self.info.set( - path = path, - infile = infile, - prefix = prefix + if len(file)>0: + if file.endswith('INCAR'): + incar = file + prefix = file.replace('INCAR','').strip() + elif file.endswith('OUTCAR'): + prefix = file.replace('OUTCAR','').strip() + else: + self.error('please provide the path to an INCAR or OUTCAR file') + #end if + outcar = prefix+'OUTCAR' + xmlfile = prefix+'vasprun.xml' + if prefix=='': + prefix=None + #end if + #end if + self.info = obj( + path = path, + prefix = prefix, + incar = incar, + outcar = outcar, + xmlfile = xmlfile, + xml = xml ) if analyze: self.analyze() #end if #end def __init__ - def analyze(self): + def analyze(self,outcar=None): + if outcar is None and self.info.outcar!=None: + outcar = os.path.join(self.info.path,self.info.outcar) + #ned if if self.info.xml: - xmlfile = 'vasprun.xml' - if self.info.prefix!=None: - xmlfile = self.info.prefix+xmlfile - #end if - self.xmldata = read_vxml(os.path.join(self.info.path,xmlfile)) + self.xmldata = read_vxml(os.path.join(self.info.path,self.info.xmlfile)) + #end if + if outcar!=None: + self.analyze_outcar(outcar) #end if #end def analyze + + + def analyze_outcar(self,outcar): + if not os.path.exists(outcar): + self.error('outcar file {0} does not exist'.format(outcar)) + #end if + oc = open(outcar,'r') + lines = oc.read().splitlines() + oc.close() + del oc + # gather initialization lines + init = [] + n = 0 + for line in lines: + if len(line)>0 and line[0]=='-' and 'Iteration' in line: + break + #end if + init.append(line) + n+=1 + #end for + # gather lines for each iteration + ion_steps = obj() + for line in lines[n:]: + if len(line)>0 and line[0]=='-' and 'Iteration' in line: + iteration = [] + inum,enum = line.strip(' -Iteration)').split('(') + inum = int(inum) + enum = int(enum) + if not inum in ion_steps: + ion_steps[inum] = obj() + #end if + ion_steps[inum][enum] = OutcarData(lines=iteration) + #end if + iteration.append(line) + #end for + del lines + del n + # read data from each iteration + if len(ion_steps)>0: + imax = array(ion_steps.keys(),dtype=int).max() + for inum,ion_step in ion_steps.iteritems(): + ilast = inum==imax + if len(ion_step)>0: + emax = array(ion_step.keys(),dtype=int).max() + for enum,elec_step in ion_step.iteritems(): + elast = enum==emax + elec_step.read(ilast,elast,all=False) + if ilast and elast: + self.transfer_from(elec_step) + #end if + #end for + #end if + #end for + #end if + self.ion_steps = ion_steps + #end def analyze_outcar #end class VaspAnalyzer