class PureGaugeORATask(ConfigGenerator): loadg = InputFile( '{loadg_filename_prefix}_{Ns:d}_{Nt:d}_{beta:g}_{k4:g}_{k6:g}_{label}_{traj:d}' ) fout = File( '{fout_filename_prefix}_{Ns:d}_{Nt:d}_{beta:g}_{k4:g}_{k6:g}_{label}_{traj:d}' ) fout_filename_prefix = 'ora' saveg = File( '{saveg_filename_prefix}_{Ns:d}_{Nt:d}_{beta:g}_{k4:g}_{k6:g}_{label}_{traj:d}' ) saveg_filename_prefix = 'cfgPg' binary = None # Specify this in run-specification scripts def __init__( self, # Application-specific required arguments Ns, Nt, beta, label, # Application-specific defaults warms=0, nsteps=4, qhb_steps=1, tpm=10, # Override ConfigGenerator defaults (Must pass to superconstructor manually) req_time=600, n_traj=100, # Arguments to pass along to superclass **kwargs): """Run a MILC pure-gauge ORA binary. Args (superclass): seed (required): Seed for random number generator starter (required): None, a filename, or a ConfigGenerator. start_traj (required if starter is a filename): Trajectory number of provided starter configuration. ntraj: Number of trajectories to run (after warmup) in total Args (this application): Ns (int): Number of lattice points in spatial direction Nt (int): Number of lattice points in temporal direction beta: Lattice beta parameter nsteps (int): Number of overrelaxation steps per trajectory qhb_steps (int): Number of heatbath steps per trajectory tpm (int): Trajectories per measurement (1=every traj, 2=every other traj, etc.) warms (int): Number of warmup trajectories to run label (str): Text label for the ensemble """ super(PureGaugeORATask, self).__init__(req_time=req_time, n_traj=n_traj, **kwargs) self.Ns = Ns self.Nt = Nt self.beta = beta self.label = label self.warms = warms self.nsteps = nsteps self.qhb_steps = qhb_steps self.tpm = tpm def build_input_string(self): input_str = super(PureGaugeORATask, self).build_input_string() input_dict = self.to_dict() # Saveg/loadg logic if should_load_file(self.loadg): input_dict['load_gauge'] = 'reload_serial {0}'.format(self.loadg) else: input_dict['load_gauge'] = 'fresh' if should_save_file(self.saveg): input_dict['save_gauge'] = 'save_serial {0}'.format(self.saveg) else: input_dict['save_gauge'] = 'forget' input_str += pure_gauge_ora_input_template.format(**input_dict) return input_str def verify_output(self): ## In the future, we can define custom exceptions to distinguish the below errors, if needed super(PureGaugeORATask, self).verify_output() # Check for errors # Trailing space avoids catching the error_something parameter input with open(str(self.fout)) as f: for line in f: if "error " in line: raise RuntimeError( "ORA ok check fails: Error detected in " + self.fout) # Check that the appropriate number of GMESes are present count_gmes = 0 count_exit = 0 with open(str(self.fout)) as f: for line in f: if line.startswith("GMES"): count_gmes += 1 elif line.startswith("exit: "): count_exit += 1 expect_gmes = self.n_traj / self.tpm if count_gmes < expect_gmes: raise RuntimeError("HMC ok check fails: Not enough GMES in " + self.fout + " %d/%d" % (count_gmes, expect_gmes)) if count_exit < 1: raise RuntimeError("HMC ok check fails: No exit in " + self.fout)
class SingleRepHMCTask(ConfigGenerator): loadg = InputFile( '{loadg_filename_prefix}_{Ns:d}_{Nt:d}_{beta:g}_{k4:g}_{k6:g}_{label}_{traj:d}' ) fout = File( '{fout_filename_prefix}_{Ns:d}_{Nt:d}_{beta:g}_{k4:g}_{k6:g}_{label}_{traj:d}' ) fout_filename_prefix = 'hmc' saveg = File( '{saveg_filename_prefix}_{Ns:d}_{Nt:d}_{beta:g}_{k4:g}_{k6:g}_{label}_{traj:d}' ) saveg_filename_prefix = 'cfg' binary = None # Specify this in run-specification scripts def __init__( self, # Application-specific required arguments Ns, Nt, beta, kappa, irrep, label, nsteps1, # Application-specific defaults gammarat=125., trajL=1.0, warms=0, nsteps_gauge=6, n_safe=5, safe_factor=4, tpm=1, nsteps2=None, shift=0.2, # Hasenbuch preconditioning minAR=4, maxcgobs=500, maxcgpf=500, cgtol=1e-6, # Override ConfigGenerator defaults (Must pass to superconstructor manually) req_time=600, n_traj=10, # Arguments to pass along to superclass **kwargs): """Run the Multirep MILC HMC binary with a single fermion irrep. Intended to run limiting-case F-only and A2-only theories for SU(4) 2xF 2xA2 study. Args (superclass): seed (required): Seed for random number generator starter (required): None, a filename, or a ConfigGenerator. start_traj (required if starter is a filename): Trajectory number of provided starter configuration. n_traj (int): Number of trajectories to run (after warmup) in total Args (this application): Ns (int): Number of lattice points in spatial direction Nt (int): Number of lattice points in temporal direction beta: Lattice beta parameter gammarat: NDS action parameter. beta/gamma = gammarat, so gamma = beta/gammarat. kappa: Kappa parameter for fermions irrep: Irrep of fermions ('f', 'as2'; also supports 'g', 's2', but must override default naming conventions!) label (str): Text label for the ensemble nsteps1 (int): Number of outmost-layer steps in integration. Number of steps between full D^-2 evals where we evaluate (D^2 + m^2 / D^2)^-1 instead. nsteps2 (int): No Hasenbuch if not provided. Number of gauge steps between (D^2 + m^2 / D^2)^-1 evaluations. nsteps_gauge (int): Number of innermost (gauge-only) integration steps. shift: Fake m to use in D^2 + m^2. Ignored (set to zero) if nsteps2 is not provided. trajL: Length of HMC trajectory (always 1). n_safe (int): Run a safe trajectory once every n_safe trajectories (c.f. tpm) safe_factor (int): Safe trajectories have safe_factor*nsteps1 many outermost steps tpm (int): Trajectories per measurement (1=every traj, 2=every other traj, etc.) warms (int): Number of warmup trajectories to run minAR (int): Minimum number of accepts for task to succeed maxcgobs (int): Maximum number of CG iterations to run for fermion observables. maxcgpf (int): Maximum number of CG iterations to run for pseudofermions. cgtol: Maximum CG error per site for pseudofermions and fermion observables. """ super(SingleRepHMCTask, self).__init__(req_time=req_time, n_traj=n_traj, **kwargs) self.Ns = Ns self.Nt = Nt self.beta = beta self.gammarat = gammarat self.label = label # Kappa and irrep logic self.kappa = kappa self.irrep = conventionalized_irrep(irrep) self.irrep_milc = milc_irrep_names[self.irrep] # In context of Multirep study, single-rep theories are limiting cases (other kappa=0) if self.irrep == 'f': self.k4 = kappa self.k6 = 0 elif self.irrep == 'a2': self.k4 = 0 self.k6 = kappa self.nsteps1 = nsteps1 self.nsteps2 = nsteps2 self.nsteps_gauge = nsteps_gauge if nsteps2 is None: shift = 0 # No shift if not using Hasenbuch self.shift = shift self.trajL = trajL self.n_safe = n_safe self.safe_factor = safe_factor self.tpm = tpm self.warms = warms self.minAR = minAR self.maxcgobs = maxcgobs self.maxcgpf = maxcgpf self.cgtol = cgtol # Overridable dynamic attribute for nsteps_safe, uses nsteps1*safe_factor def _dynamic_get_nsteps_safe(self): return self.nsteps1 * self.safe_factor nsteps_safe = fixable_dynamic_attribute( private_name='_nsteps_safe', dynamical_getter=_dynamic_get_nsteps_safe) def build_input_string(self): input_str = super(SingleRepHMCTask, self).build_input_string() input_dict = self.to_dict() # Saveg/loadg logic if should_load_file(self.loadg): input_dict['load_gauge'] = 'reload_serial {0}'.format(self.loadg) else: input_dict['load_gauge'] = 'fresh' if should_save_file(self.saveg): input_dict['save_gauge'] = 'save_serial {0}'.format(self.saveg) else: input_dict['save_gauge'] = 'forget' # Hasenbuch logic if self.nsteps2 is None: input_dict['L2_pf'] = '' input_dict['npseudo'] = 1 input_dict['nlevels'] = 1 input_dict['_nsteps2'] = ''.format(n2=self.nsteps2) else: input_dict['L2_pf'] = L2_pf_template.format(**input_dict) input_dict['npseudo'] = 2 input_dict['nlevels'] = 2 input_dict['_nsteps2'] = 'nstep {n2}'.format(n2=self.nsteps2) input_str += hmc_input_template.format(**input_dict) return input_str def verify_output(self): ## In the future, we can define custom exceptions to distinguish the below errors, if needed super(SingleRepHMCTask, self).verify_output() # Check for errors # Trailing space avoids catching the error_something parameter input with open(str(self.fout)) as f: for line in f: if "error " in line: raise RuntimeError( "HMC ok check fails: Error detected in " + self.fout) # Check that the appropriate number of GMESes are present count_gmes = 0 count_traj = 0 count_exit = 0 count_accept = 0 with open(str(self.fout)) as f: for line in f: if line.startswith("GMES"): count_gmes += 1 elif line.startswith("exit: "): count_exit += 1 elif line.startswith("ACCEPT") or line.startswith( "SAFE_ACCEPT"): count_traj += 1 count_accept += 1 elif line.startswith("REJECT") or line.startswith( "SAFE_REJECT"): count_traj += 1 if (count_traj < self.n_traj) and (count_gmes < self.n_traj): raise RuntimeError("HMC ok check fails: Not enough GMES or ACCEPT/REJECT in " + self.fout +\ " %d/%d, %d/%d"%(self.n_traj,count_traj,self.n_traj,count_gmes)) if count_exit < 1: raise RuntimeError("HMC ok check fails: No exit in " + self.fout) if count_accept < self.minAR: raise RuntimeError( "HMC ok check fails: %d acceptances < specified minimum %d" % (count_accept, self.minAR))
class ChimeraTask(MCMC): fout = File( 'outCt_{Ns:d}{Nt:d}_b{beta:g}_kf{k4:g}_kas{k6:g}_{irrep}_{r0:g}gf_{traj:d}' ) loadp_f = InputFile( 'prop_{Ns:d}{Nt:d}_b{beta:g}_kf{k4:g}_kas{k6:g}_{irrep}_{r0:g}gf_{traj:d}', postprocessor=_wijay_volume_postprocessor, auto_parse=False) loadp_as = InputFile( 'prop_{Ns:d}{Nt:d}_b{beta:g}_kf{k4:g}_kas{k6:g}_{irrep}_{r0:g}gf_{traj:d}', postprocessor=_wijay_volume_postprocessor, auto_parse=False) saveg = None binary = '/nfs/beowulf03/wijay/mrep/bin/ci_chimera_baryon_spec_only' def __init__( self, # Application-specific required arguments loadp_f, loadp_as, # Override ConfigMeasurement defaults req_time=60 * 60, # 1 hour # Application-specific defaults Ns=None, Nt=None, k4=None, k6=None, r0_4=None, r0_6=None, # Arguments to pass along to superclass **kwargs): """ Computes chimera baryon spectroscopy using saved propagator files. Args: loadp_f: str, full path to the fundamental propagator binary file loadp_as: str, full path to the sextet propagator binary file req_time: int, the requested time for the task in seconds, \ default is 1 hour Ns: int, spatial lattice size, default is None \ (parses from input filename) Nt: int, temporal lattice size, default is None \ (parses from input filename) k4: float, fundamental hopping parameter, default is None \ (parses from input filename) k6: float, sextet hopping parameter, default is None \ (parses from input filename) r0_4: float, fundamental sink smearing radius, default is None \ (matches to the smearing radius of the source, read from the propagator input filename) r0_6: float, sextet sink smearing radius, default is None \ (matches to the smearing radius of the source, read from the propagator input filename) Returns: ChimeraTask instance """ super(ChimeraTask, self).__init__(req_time=req_time, **kwargs) # Propagator saving/loading # Force params to agree params_f = self.loadp_f.parse_params(loadp_f) params_as = self.loadp_as.parse_params(loadp_as) for key in ['beta', 'Ns', 'Nt', 'k4', 'k6']: assert params_f[key] == params_as[key],\ "Error: mismatched values for {key} between the props".format(key=key) # Parameters are not auto-parsed out of filenames self.loadp_f = loadp_f self.loadp_as = loadp_as # Load manually self.beta = params_f['beta'] self.k4 = params_f['k4'] self.k6 = params_f['k6'] self.Ns = params_f['Ns'] self.Nt = params_f['Nt'] self.r0_4 = params_f['r0'] self.r0_6 = params_as['r0'] self.irrep = 'mixed' # chimeras are mixed-rep objects # Override values parsed from input filenames if Ns is not None: self.Ns = Ns if Nt is not None: self.Nt = Nt if k4 is not None: self.k4 = k4 if k6 is not None: self.k6 = k6 if r0_4 is not None: self.r0_4 = r0_4 if r0_6 is not None: self.r0_6 = r0_4 def build_input_string(self): input_str = super(ChimeraTask, self).build_input_string() input_dict = self.to_dict() input_dict['load_prop_f'] = 'reload_serial_wprop {loadp_f}'.format( loadp=self.loadp_f) input_dict['load_prop_as'] = 'reload_serial_wprop {loadp_as}'.format( loadp=self.loadp_as) return input_str + chimera_input_template.format(**input_dict) def verify_output(self): super(ChimeraTask, self).verify_output() with open(str(self.fout)) as f: found_running_completed = False for line in f: found_running_completed |= ("get_i(0): EOF on input" in line) if not found_running_completed: raise RuntimeError( "Spectro ok check fails: running did not complete in " + self.fout)
class FlowTask(ConfigMeasurement): ## File naming conventions loadg = InputFile( '{loadg_filename_prefix}_{Ns:d}_{Nt:d}_{beta:g}_{k4:g}_{k6:g}_{label}_{traj:d}' ) fout = File( '{fout_filename_prefix}_{Ns:d}_{Nt:d}_{beta:g}_{k4:g}_{k6:g}_{label}_{traj:d}' ) fout_filename_prefix = 'flow' saveg = None binary = None # Specify this in run-specification scripts def __init__( self, # Application-specific required arguments tmax, # Override ConfigMeasurement defaults req_time=600, # Application-specific defaults minE=0, mindE=0.0, epsilon=0.01, xi=None, # Overrides Ns=None, Nt=None, # Arguments to pass along to superclass **kwargs): """Perform the Wilson Flow on a gauge configuration. If starter is a filename, attempts to read parameters from filename. If starter is a ConfigGenerator, steals parameters from the GaugeGenerator. Args: starter: A filename or a ConfigGenerator. Ns: Number of lattice points in spatial direction. If provided, overrides whatever was found in the ConfigGenerator or filename. Nt: Number of lattice points in temporal direction. If provided, overrides whatever was found in the ConfigGenerator or filename. epsilon: Step size for numerical integration of flow tmax: Terminate flow at t=tmax. If tmax=0, uses adaptive flow stopping. minE: Terminate flow when <t^2 E(t)> >= minE mindE: Terminate flow when <t d/dt t^2 E(t)> >= mindE """ super(FlowTask, self).__init__(req_time=req_time, **kwargs) # Physical parameters self.tmax = tmax self.minE = minE self.mindE = mindE self.epsilon = epsilon self.xi = xi # Override parameters read out from a filename or stolen from a ConfigGenerator if Ns is not None: self.Ns = Ns if Nt is not None: self.Nt = Nt # Don't run trivial flows if tmax == 0: assert minE != 0 or mindE != 0, \ "If tmax is 0, must set adaptive flow parameters minE and mindE or flow will be trivial" def build_input_string(self): input_str = super(FlowTask, self).build_input_string() input_dict = self.to_dict() if self.xi is not None: input_dict['xi_str'] = 'xi {xi}'.format(xi=self.xi) else: input_dict['xi_str'] = '' return input_str + flow_input_template.format(**input_dict)
class MCMC(tasks.Runner): """Abstract superclass for Runners that run binaries from typical MCMC suites (e.g., MILC).""" ## Modular file naming conventions # Output files saveg_filename_prefix = 'cfg' saveg = File(conventions="{saveg_filename_prefix}_{traj:d}", save=True) fout_filename_prefix = 'fout' fout = File(conventions="{fout_filename_prefix}_{traj:d}", save=True) # Input files -- Won't be tracked by rollbacker, automatically parse and load parameters loadg = InputFile(conventions="{loadg_filename_prefix}_{traj:d}", save=False) def __init__(self, save_config=True, **kwargs): super(MCMC, self).__init__(**kwargs) if self.saveg is not None: self.saveg.save = save_config def build_input_string(self): """Take a heredoc, terminating in EOF, as input. Reroute output to output file self.fout """ input_str = super(MCMC, self).build_input_string().strip() input_str += "<< EOF >> {0}\n".format(self.fout) return input_str ## Common "start from"/"measure on" behavior (load params from config_generator or filename) def start_from_config_generator(self, config_generator): """Steal parameters from specified config_generator. Stores privileged MCMC attribute names like fout, saveg, loadg (listed in mcmc.privileged_param_names) as 'cg_...' to not clobber anything important. """ assert isinstance(config_generator, ConfigGenerator) cg_dict = config_generator.to_dict() # Remove metainfo from cg_dict for special_key in tasks.special_keys: cg_dict.pop(special_key, None) # Rename certain dangerously-named parameters like '...'->'cg_...' for fix_param in privileged_param_names: if cg_dict.has_key(fix_param): cg_dict['cg_' + fix_param] = cg_dict.pop(fix_param) # Load parameters from CG in to this object for k, v in cg_dict.items(): if getattr( self, k, None) is None: # Don't override anything already present setattr(self, k, v) # Need the config generator to run first self.depends_on.append(config_generator) # Set loadg without parsing if isinstance(self.loadg, basestring): del self.loadg # Remove any override that is present self.loadg._value_override = config_generator.saveg def start_from_config_file(self, loadg, delay_fn_exists_check=True): """Sets up MCMC task to run the specified config file loadg. Uses file naming conventions (see taxi.file) to parse parameters from the filename. Specified config file must exist at time of task specification unless self.delay_fn_exists_check. """ assert loadg is not None loadg = sanitized_path(str(loadg)) if not delay_fn_exists_check: assert os.path.exists( loadg ), "Need a valid path to a configuration; {s} does not exist".format( s=loadg) self.loadg = loadg # Automatically parses out parameters and loads them in to the object def execute(self, cores=None): """Versus Runner, checks to make sure loadg exists before running. """ assert not should_load_file(self.loadg) or os.path.exists(str(self.loadg)),\ "Error: file {loadg} does not exist.".format(loadg=self.loadg) super(MCMC, self).execute(cores=cores) ## Standard output verification def verify_output(self): """Checks to make sure that output file fout and output gauge configuration saveg exist after running. """ super(MCMC, self).verify_output() ## In the future, we can define custom exceptions to distinguish the below errors, if needed # If this task should save a gauge file, that gauge file must exist if should_save_file( self.saveg) and not os.path.exists(str(self.saveg)): print "MCMC ok check fails: Config file {0} doesn't exist.".format( self.saveg) raise RuntimeError # If this task should save an output file, that output file must exist if should_save_file(self.fout) and not os.path.exists(str(self.fout)): print "MCMC ok check fails: Output file {0} doesn't exist.".format( self.fout) raise RuntimeError
class OverlapTask(ConfigMeasurement): ## File naming conventions loadg = InputFile( 'cfg_{Ns:d}{Nt:d}_b{beta:g}_kf{k4:g}_kas{k6:g}_{label}_{traj:d}', postprocessor=_wijay_volume_postprocessor, auto_parse=False) saveg = File( 'cfg_{Ns:d}{Nt:d}_b{beta:g}_kf{k4:g}_kas{k6:g}_{label}_{traj:d}') loadp = InputFile( 'prop_{Ns:d}{Nt:d}_b{beta:g}_kf{k4:g}_kas{k6:g}_{irrep}_{r0:g}gf_{traj:d}', postprocessor=_wijay_volume_postprocessor, auto_parse=False) savep = File( 'prop_{Ns:d}{Nt:d}_b{beta:g}_kf{k4:g}_kas{k6:g}_{irrep}_{r0:g}gf_{traj:d}' ) load_h0 = InputFile( 'h0_{Ns:d}{Nt:d}_b{beta:g}_kf{k4:g}_kas{k6:g}_{traj:d}', postprocessor=_wijay_volume_postprocessor, auto_parse=False) save_h0 = File('h0_{Ns:d}{Nt:d}_b{beta:g}_kf{k4:g}_kas{k6:g}_{traj:d}') load_hov = InputFile( 'hov_{Ns:d}{Nt:d}_b{beta:g}_kf{k4:g}_kas{k6:g}_{traj:d}', postprocessor=_wijay_volume_postprocessor, auto_parse=False) save_hov = File('hov_{Ns:d}{Nt:d}_b{beta:g}_kf{k4:g}_kas{k6:g}_{traj:d}') def __init__(self, number_of_masses, m0, error_for_propagator, source_type, r0, n_inner_eigenvals, n_h0_eigenvals, n_hov_eigenvals, prec_sign, zolo_min, zolo_max, inner_cg_iters, inner_residue, inner_residue_h, max_rayleigh_iters, max_r0_iters, restart_rayleigh, kalkreuter_iters, eigenvec_quality, eigenval_tol_low, error_decr_low, eigenval_tol_high, error_decr_high, req_time, **kwargs): super(OverlapTask, self).__init__(req_time=req_time, **kwargs) self.number_of_masses = number_of_masses self.m0 = m0 self.error_for_propagator = error_for_propagator self.source_type = source_type self.r0 = r0 ###################################################### # Hard-coded values for multimass conjugate gradient # ###################################################### self.scalez = 1.0 # Additional rescaling of dslash self.max_cg_iters = 500 # Used if doing CG, else not used self.max_cg_restarts = 1 # Used if doing CG, else not used #################################### # Specifying number of eigenvalues # #################################### assert (n_h0_eigenvals == 2*n_hov_eigenvals),\ "Error: Must have h_h0_eigenvals == 2*n_hov_eigenvals" self.n_inner_eigenvals = n_inner_eigenvals self.n_h0_eigenvals = n_h0_eigenvals self.n_hov_eigenvals = n_hov_eigenvals ###################################### # Params for Zolotarov step function # ###################################### self.prec_sign = prec_sign self.zolo_min = zolo_min self.zolo_max = zolo_max self.inner_cg_iters = inner_cg_iters self.inner_residue = inner_residue self.inner_residue_h = inner_residue_h ################################ # Params for eigenvalue finder # ################################ self.max_rayleigh_iters = max_rayleigh_iters self.max_r0_iters = max_r0_iters self.restart_rayleigh = restart_rayleigh self.kalkreuter_iters = kalkreuter_iters self.eigenvec_quality = eigenvec_quality self.eigenval_tol_low = eigenval_tol_low self.error_decr_low = error_decr_low self.eigenval_tol_high = eigenval_tol_high self.error_decr_high = error_decr_high def construct_seed(self): """ Construct a reaonable seed for the random number generator. """ self.seed = int("{0}{1}{2}{3}".format(self.Ns, self.Nt, int((self.beta * 100) // 2), self.loadg.split('_')[-1])) def reformat_args_for_input(self): """ Reformat the arguments 'm0' and 'error_for_propagator'. These input lines \ depend on the value of 'number_of_masses'; there should be one line for \ each mass. """ # Make sure the m0 and error_for_propagator are lists try: len(self.m0) except TypeError: self.m0 = [self.m0] try: len(self.error_for_propagator) except: self.error_for_propagator = [self.error_for_propagator] # Do lists have the correct length for the specified number of masses? assert ((len(self.m0) == self.number_of_masses) and (len(self.error_for_propagator) == self.number_of_masses)),\ "Error: 'number_of_masses' = {0}. Must specify {0} values for 'm0' and 'error_for_propagator'".\ format(self.number_of_masses) # Reformat for input file with one entry per line self.m0 = '\n'.join(['m0 ' + str(val) for val in self.m0]) self.error_for_propagator =\ '\n'.join(['error_for_propagator '+str(val) for val in self.error_for_propagator]) def build_input_string(self): input_str = super(OverlapTask, self).build_input_string() input_dict = self.to_dict() ## Gauge I/O if should_load_file(self.loadg): input_dict['load_gauge'] = 'reload_serial {loadg}'.format( loadg=self.loadg) else: input_dict['load_gauge'] = 'fresh' if should_save_file(self.saveg): input_dict['save_gauge'] = 'save_serial {saveg}'.format( saveg=self.saveg) else: input_dict['save_gauge'] = 'forget' ## Gauge fixing if self.gauge_fix is None: input_dict['gauge_fix'] = 'no_gauge_fix' elif 'landau' in self.gauge_fix: input_dict['gauge_fix'] = 'landau_gauge_fix' elif 'coulomb' in self.gauge_fix: input_dict['gauge_fix'] = 'coulomb_gauge_fix' else: msg = "Error: invalid gauge_fixing command '{0}' encountered.".format( self.gauge_fix) raise RuntimeError(msg) ## Prop I/O if should_load_file(self.loadp): input_dict['load_prop'] = 'reload_serial_wprop {loadp}'.format( loadp=self.loadp) else: input_dict['load_prop'] = 'fresh_wprop' if should_save_file(self.savep): input_dict['save_prop'] = 'save_serial_wprop {savep}'.format( savep=self.savep) else: input_dict['save_prop'] = 'forget_wprop' ## h0 modes I/O if should_load_file(self.load_h0): # Leading i for 'input' input_dict['load_h0'] = 'iserial_hr0_modes {load_h0}'.format( load_h0=self.load_h0) else: input_dict['load_h0'] = 'fresh_hr0_modes' if should_save_file(self.save_h0): input_dict['save_h0'] = 'serial_hr0_modes {save_h0}'.format( save_h0=self.save_h0) else: input_dict['save_h0'] = 'forget_hr0_modes' ## hov modes I/O if should_load_file(self.load_hov): # Leading i for 'input' input_dict['load_hov'] = 'iserial_hov_modes {load_hov}'.format( load_hov=self.load_hov) else: input_dict['load_hov'] = 'fresh_hov_modes' if should_save_file(self.save_hov): input_dict['save_hov'] = 'serial_hov_modes {save_hov}'.format( save_hov=self.save_hov) else: input_dict['save_hov'] = 'forget_hov_modes' return input_str + overlap_template.format(**input_dict)
class OverlapPropagatorTask(OverlapTask): ## File naming conventions fout = File( 'outPropOverlap_{Ns:d}{Nt:d}_b{beta:g}_kf{k4:g}_kas{k6:g}_{irrep}_{r0:g}_{traj:d}' ) saveg = None save_h0 = None save_hov = None loadp = None binary = '/nfs/beowulf03/wijay/mrep/bin/su3_ov_eig_cg_multi' def __init__( self, ## I/O loadg, savep, load_h0, load_hov, m0=[0.0], error_for_propagator=[1e-6], source_type='point', r0=0.0, ## For taxi req_time=600, ## Override autodetection from loadg beta=None, Ns=None, Nt=None, irrep='f', ## Numbers of eigenvalues n_inner_eigenvals=10, n_h0_eigenvals=16, n_hov_eigenvals=8, ## Zolotarov prec_sign=1e-7, zolo_min=0.01, zolo_max=2.7, inner_cg_iters=1000, inner_residue=1e-7, inner_residue_h=1e-7, ## Eigenvalue finder max_rayleigh_iters=0, max_r0_iters=0, restart_rayleigh=10, kalkreuter_iters=10, eigenvec_quality=1.0e-4, eigenval_tol_low=1.0e-6, error_decr_low=0.3, eigenval_tol_high=1.0e-7, error_decr_high=0.3, ## Topology topology=200, **kwargs ## Should inlcude 'measure_on' for ConfigMeasurement ): """ doc string here """ if loadg is None: raise ValueError("Error: Must specify loadg") if savep is None: raise ValueError("Error: Must specify savep") if load_h0 is None: raise ValueError("Error: Must specify load_h0") if load_hov is None: raise ValueError("Error: Must specify load_hov") number_of_masses = len(m0) if len(error_for_propagator) != number_of_masses: assert len(error_for_propagator) == 1,\ "Error: poorly formatted 'error_for_propagator'; check the length of the list." error_for_propagator = [error_for_propagator[0] for _ in m0] params = self.loadg.parse_params(loadg) self.beta = params['beta'] self.Ns = params['Ns'] self.Nt = params['Nt'] self.irrep = irrep ## Override parameters read out from a filename or stolen from a ConfigGenerator if beta is not None: self.beta = beta if Ns is not None: self.Ns = Ns if Nt is not None: self.Nt = Nt OverlapTask.__init__(self,\ number_of_masses, m0, error_for_propagator,\ source_type, r0,\ n_inner_eigenvals, n_h0_eigenvals, n_hov_eigenvals,\ prec_sign, zolo_min, zolo_max,\ inner_cg_iters, inner_residue, inner_residue_h,\ max_rayleigh_iters, max_r0_iters, restart_rayleigh,\ kalkreuter_iters, eigenvec_quality,\ eigenval_tol_low, error_decr_low,\ eigenval_tol_high, error_decr_high,\ req_time, **kwargs) ####################### # Hard-coded settings # ####################### self.gauge_fix = None # Never fix the gauge, assumed to be done already self.saveg = None # Never save gauge config, only read self.save_h0 = None # Never save h0 modes, only ready self.save_hov = None # Never save hov modes, only read self.loadp = None # Never load a propagator when preconditioning to compute a propagator self.u0 = 1.0 # tadpole improvement term from MILC. Default is 1.0 self.R0 = 1.2 # The GW radius; present action uses 1.2 self.topology = 200 ############ # File I/O # ############ assert loadg is not None,\ "Error: Must load gauge config for OverlapPropagator" self.loadg = loadg assert savep is not None,\ "Error: Saving a propagator is the goal of OverlapPropagator" self.savep = savep assert load_h0 is not None,\ "Error: OverlapPropagator assumes h0 eigenvalues have been computed. Please load them." self.load_h0 = load_h0 assert load_hov is not None,\ "Error: OverlapPropagator assumes hov eigenvalues have been computed. Please load them." self.load_hov = load_hov OverlapTask.construct_seed(self) OverlapTask.reformat_args_for_input(self) def verify_output(self): super(OverlapPropagatorTask, self).verify_output() # Confirm presence of saved gauge file if not os.path.exists(str(self.savep)): msg = "OverlapPropagator verification failure: missing saved propagator {0}".format( self.savep) raise RuntimeError(msg) # Check for well-formed output file # Trailing space avoids catching the error_something parameter input with open(str(self.fout)) as f: found_end_of_reading = False found_running_completed = False for line in f: if "error " in line.lower(): raise RuntimeError( "Spectro ok check fails: Error detected in " + str(self.fout)) found_running_completed |= ("RUNNING COMPLETED" in line) found_end_of_reading |= ("Time to check unitarity" in line) if not found_end_of_reading: raise RuntimeError( "OverlapPropagator verification failure: did not find end of reading in " + str(self.fout)) if not found_running_completed: raise RuntimeError( "OverlapPropagator verification failure: running did not complete in " + str(self.fout))
class OverlapPreconditionTask(OverlapTask): ## File naming conventions fout = File( 'outOverlapModes_{Ns:d}{Nt:d}_b{beta:g}_kf{k4:g}_kas{k6:g}_{traj:d}') loadp = None savep = None load_h0 = None load_hov = None binary = '/nfs/beowulf03/wijay/mrep/bin/su3_ov_eig_cg_f_hyp' def __init__( self, ## I/O loadg=None, saveg=None, save_h0=None, save_hov=None, ## For taxi req_time=600, ## Override autodetection from loadg beta=None, Ns=None, Nt=None, irrep='f', gauge_fix='landau_gauge_fix', error_for_propagator=1e-6, ## Numbers of eigenvalues n_inner_eigenvals=12, n_h0_eigenvals=16, n_hov_eigenvals=8, ## Zolotarov prec_sign=1e-7, zolo_min=0.01, zolo_max=2.7, inner_cg_iters=1000, inner_residue=1e-7, inner_residue_h=1e-7, ## Eigenvalue finder max_rayleigh_iters=100, max_r0_iters=100, restart_rayleigh=10, kalkreuter_iters=10, eigenvec_quality=1.0e-4, eigenval_tol_low=1.0e-6, error_decr_low=0.3, eigenval_tol_high=1.0e-7, error_decr_high=0.3, ## Topology topology=200, **kwargs ## Should inlcude 'measure_on' for ConfigMeasurement ): """ Computes exact eigenvalues of <?> and <?> to 'precondition' the computation of overlap propagators. Because the binary itself requires many input parameters, this class has \ many parameters. Mostly we try to use sensible default values. Args: # Required arguments req_time: int, the requested time (in seconds) for the task beta: float, the inverse gauge coupling loadg: str, the full path to the gauge file to load saveg: str, the full path for saving the gauge file. save_h0: str, the full path for saving eigenvalues of h(0) save_hov: str, the full path for saving eigenvalues of ?? gauge_fix: str, the gauge to which to fix. Default is 'landau'. \ If None, will not fix the gauge. # Optional arguments (those with defaults) n_inner_eigenvals: int, number of eigenvalues of h(-R0) to compute, \ where R0 is the GW radius. Default is 12. n_h0_eigenvals: int, number of eigenvalues of h(0) to compute. Must \ be 2 x n_hov_eigenvals below. Default is 16. n_hov_eigenvals: int, number of eigenvaluess of H(0) to compute. Must \ be 1/2 x n_h0_eigenvals above. Default is 8. prec_sign: float, desired accuracy for Zolotarov step function. \ Default is 1e-7 zolo_min: float, minimum range for computing Zolotarov step function. \ Default is 0.01 zolo_max: float, maximum range for computing Zolotarov step function. \ Default is 2.7 inner_cg_iterations: int, number of iterations for the conjugate \ gradient used to compute the Zolotarov step function. Default is \ 1000 inner_residue: float, the conjugate gradient residue used to compute \ the Zolotarov step function. Default is 1e-7. The code holds this \ value as 'resid_inner_save' inner_residue_h: float, used in build_hr0_field2.c. Only used if precflag=HIGHP is set. Default is 1e-7. max_rayleigh_iters: int,??. Default is 100. max_r0_iters: int, ??. Default is 100. restart_rayleigh: int, ??. Default is 10. kalkreuter_iters: int, ??. Default is 10. eigenvec_quality: float, ??. Default is 1.0e-4. eigenval_tol_low: float, ??. Default is 1.0e-6. error_decr_low: float, ??. Default is 0.3. eigenval_tol_high: float, ??. Default is1.0e-7. error_decr_high: float, ??. Default is 0.3. topology: int, how to handle the topolgy. This feature is used more \ in the dynamical overlap code, which keeps track of topolgy. If = -100 uses current topology. If <= -100, reads topology from gauge info file. If >= 100, allocates space for Nvecs_hov+abs(current_topology)/100 + 2 H(0) modes. If < 100, Nvecs_hov+abs(current_topology)+2 modes/ If >= 100, find current topology before start of trajectory. kwargs: keyword arguments to pass to super. Should include the \ keyword 'measure_on' for ConfigMeasurement. If 'measure_on' is \ a filename, the code attemps to detect beta, Ns, and NT from the filename. TODO: Implement support for starting with a ConfigGenerator. Returns: OverlapPreconditionTask instance """ if loadg is None: raise ValueError("Error: Must specify loadg") if saveg is None: raise ValueError("Error: Must specify saveg") if save_h0 is None: raise ValueError("Error: Must specify save_h0") if save_hov is None: raise ValueError("Error: Must specify save_hov") params = self.loadg.parse_params(loadg) self.beta = params['beta'] self.Ns = params['Ns'] self.Nt = params['Nt'] self.irrep = irrep ## Override parameters read out from a filename or stolen from a ConfigGenerator if beta is not None: self.beta = beta if Ns is not None: self.Ns = Ns if Nt is not None: self.Nt = Nt # No multimass CG when computing eigenmodes number_of_masses = 1 m0 = 0.0 # Hard-coded point source to make it clear no smearing occurs source_type = 'point' # Not used for eigenmode preconditioning r0 = 0.0 # Not used for eigenmode preconditioning OverlapTask.__init__(self,\ number_of_masses, m0, error_for_propagator,\ source_type, r0, n_inner_eigenvals, n_h0_eigenvals, n_hov_eigenvals,\ prec_sign, zolo_min, zolo_max,\ inner_cg_iters, inner_residue, inner_residue_h,\ max_rayleigh_iters, max_r0_iters, restart_rayleigh,\ kalkreuter_iters, eigenvec_quality,\ eigenval_tol_low, error_decr_low,\ eigenval_tol_high, error_decr_high,\ req_time, **kwargs) assert gauge_fix is not None,\ "Error: Should gauge fix to landau gauge for OverlapPreconditioning" self.gauge_fix = gauge_fix ####################### # Hard-coded settings # ####################### self.u0 = 1.0 # tadpole improvement term from MILC. Default is 1.0 self.number_of_masses = 1 # Always 1 for eigenvalue preconditioning self.m0 = 0.0 # The overlap mass. 0.0 for eigenvalue preconditioning self.R0 = 1.2 # The GW radius; present action uses 1.2 self.topology = 200 ############ # File I/O # ############ assert loadg is not None,\ "Error: Must load gauge config for OverlapPreconditioning." self.loadg = loadg assert saveg is not None,\ "Error: Must save gauge config after gauge fixing for OverlapPreconditioning." self.saveg = saveg self.loadp = None # Never load a propagator when preconditioning to compute a propagator self.savep = None # Never save a propagator when preconditioning to compute a propagator self.load_h0 = None # Never load eigenvalues; they're the end goal here! self.load_hov = None # Never load eigenvalues; they're the end goal here! assert save_h0 is not None,\ "Error: Please specify save_h0 when computing eigenvalues." self.save_h0 = save_h0 assert save_hov is not None,\ "Error: Please specify save_hov when computing eigenvalues." self.save_hov = save_hov OverlapTask.construct_seed(self) OverlapTask.reformat_args_for_input(self) def verify_output(self): super(OverlapPreconditionTask, self).verify_output() # Confirm presence of saved gauge file if not os.path.exists(str(self.saveg)): msg = "OverlapPrecondition verification failure: missing saved gauge config {0}".format( self.saveg) raise RuntimeError(msg) # Confirm presence of saved hov file if not os.path.exists(str(self.save_hov)): msg = "OverlapPrecondition verification failure: missing saved hov file {0}".format( self.save_hov) raise RuntimeError(msg) # Confirm presence of saved h0 file if not os.path.exists(str(self.save_h0)): msg = "OverlapPrecondition verification failure: missing saved h0 file {0}".format( self.save_h0) raise RuntimeError(msg) # Check for well-formed output file # Trailing space avoids catching the error_something parameter input with open(str(self.fout)) as f: found_end_of_reading = False found_running_completed = False for line in f: if "error " in line.lower(): raise RuntimeError( "Spectro ok check fails: Error detected in " + str(self.fout)) found_running_completed |= ("RUNNING COMPLETED" in line) found_end_of_reading |= ("Time to check unitarity" in line) if not found_end_of_reading: raise RuntimeError( "OverlapPrecondition verification failure: did not find end of reading in " + str(self.fout)) if not found_running_completed: raise RuntimeError( "OverlapPrecondition verification failure: running did not complete in " + str(self.fout))
class Copy(Runner): """Copy a file from src to dest. Does not overwrite anything unless told to. Unlike the usual runner, doesn't call a binary.""" binary = None ## Modularized file naming conventions # src = InputFile(...) # Unnecessary to track src, don't ever parse the fn dest = File(conventions=None, save=True) # Let rollbacker know to track this file def __init__(self, src, dest, allow_overwrite=False, req_time=60, **kwargs): super(Copy, self).__init__(req_time=req_time, **kwargs) # Store sanitized file paths assert isinstance(src, basestring) assert isinstance(dest, basestring) self.src = sanitized_path(src) self.dest = sanitized_path(dest) self.allow_overwrite = allow_overwrite def execute(self, *args, **kwargs): """Uses shutil.copy2 to copy a file from self.src to self.dest. Unless self.allow_overwrite, will not overwrite an existing file. If self.allow_overwrite, then only overwrites the file if it has been updated (determined by looking at modification times and MD5 hashes if necessary). """ assert os.path.exists(self.src), "Source file '{0}' must exist".format( self.src) if os.path.exists(self.dest): if self.allow_overwrite: ## Only overwrite if file is updated. Try to avoid hashing. file_updated = False if os.path.getmtime(self.src) > os.path.getmtime(self.dest): # Source was modifiedly more recently than dest file_updated = True elif os.stat(self.src).st_size != os.stat(self.dest).st_size: # Sizes are not the same file_updated = True else: # Do the hash. MD5 should be good enough. hash_src = hashlib.md5(open(self.src, 'rb').read()).digest() hash_dest = hashlib.md5(open(self.dest, 'rb').read()).digest() if hash_src != hash_dest: file_updated = True if not file_updated: print "Skipping copy: '{0}' = '{1}'".format( self.src, self.dest) return else: raise Exception( "Path '{0}' already exists and overwriting not allowed". format(self.dest)) dest_dirname = os.path.dirname(self.dest) if len(dest_dirname) > 0: ensure_path_exists(os.path.dirname(self.dest)) print "{0} -> {1}".format(self.src, self.dest) shutil.copy2(self.src, self.dest)