Source code for pysmac.utils.smac_input_readers

import re

[docs]def read_pcs(filename): ''' Function to read a SMAC pcs file (format according to version 2.08). :param filename: name of the pcs file to be read :type filename: str :returns: tuple -- (parameters as a dict, conditionals as a list, forbiddens as a list) ''' num_regex = "[+\-]?(?:0|[1-9]\d*)(?:\.\d*)?(?:[eE][+\-]?\d+)?" FLOAT_REGEX = re.compile("^[ ]*(?P<name>[^ ]+)[ ]*\[(?P<range_start>%s)[ ]*,[ ]*(?P<range_end>%s)\][ ]*\[(?P<default>[^#]*)\](?P<misc>.*)$" %(num_regex,num_regex)) CAT_REGEX = re.compile("^[ ]*(?P<name>[^ ]+)[ ]*{(?P<values>.+)}[ ]*\[(?P<default>[^#]*)\](?P<misc>.*)$") COND_REGEX = re.compile("^[ ]*(?P<cond>[^ ]+)[ ]*\|[ ]*(?P<head>[^ ]+)[ ]*in[ ]*{(?P<values>.+)}(?P<misc>.*)$") FORBIDDEN_REGEX = re.compile("^[ ]*{(?P<values>.+)}(?P<misc>.*)$") param_dict = {} # name -> ([begin, end], default, flags) conditions = [] forbiddens = [] with open(filename) as fp: for line in fp: #remove line break and white spaces line = line.strip("\n").strip(" ") #remove comments if line.find("#") > -1: line = line[:line.find("#")] # remove comments # skip empty lines if line == "": continue # categorial parameter cat_match = CAT_REGEX.match(line) if cat_match: name = cat_match.group("name") values = set([x.strip(" ") for x in cat_match.group("values").split(",")]) default = cat_match.group("default") #logging.debug("CATEGORIAL: %s %s {%s} (%s)" %(name, default, ",".join(map(str, values)), type_)) param_dict[name] = (values, default) float_match = FLOAT_REGEX.match(line) if float_match: name = float_match.group("name") values = [float(float_match.group("range_start")), float(float_match.group("range_end"))] default = float(float_match.group("default")) #logging.debug("PARAMETER: %s %f [%s] (%s)" %(name, default, ",".join(map(str, values)), type_)) param_dict[name] = (values, default) if "i" in float_match.group("misc"): param_dict[name] += ('int',) if "l" in float_match.group("misc"): param_dict[name] += ('log',) cond_match = COND_REGEX.match(line) if cond_match: #logging.debug("CONDITIONAL: %s | %s in {%s}" %(cond, head, ",".join(values))) conditions.append(line) forbidden_match = FORBIDDEN_REGEX.match(line) if forbidden_match: #logging.debug("FORBIDDEN: {%s}" %(values)) forbiddens.append(line) return param_dict, conditions, forbiddens
[docs]def write_pcs(pcs_filename, parameters, forbiddens, conditionals): ''' Function to write a SMAC PCS file''' with open(pcs_filename, 'w') as out: # Parameters out.write("# Parameters\n") for param, info in parameters.iteritems(): if param == 'algorithm': # Handle this specially because merge_configuration_spaces doesn't return a set values = set(info[1]) default = info[2] else: values = info[0] default = info[1] if isinstance(values, set): # Categorical line = "%(param)s {%(values)s} [%(default)s]" % dict(param=param, values=",".join(values), default=default) else: _type = '' if len(info) == 2 else info[2][0] if _type == 'i': values = map(int, info[0]) default = int(info[1]) line = "%(param)s %(values)s [%(default)s] %(_type)s" % dict(param=param, values=values, default=default, _type=_type) out.write(line +'\n') # Conditionals out.write("# Conditionals\n") for conditional in conditionals: out.write(conditional +'\n') out.write("# Forbidden\n") # Forbidden for forbidden in forbiddens: out.write(forbidden +'\n')
[docs]def read_scenario_file(fn): """ Small helper function to read a SMAC scenario file. :returns : dict -- (key, value) pairs are (variable name, variable value) """ # translate the difference option names to a canonical name scenario_option_names = {'algo-exec' : 'algo', 'algoExec': 'algo', 'algo-exec-dir': 'execdir', 'exec-dir' : 'execdir', 'execDir' : 'execdir', 'algo-deterministic' : 'deterministic', 'paramFile' : 'paramfile', 'pcs-file' :'paramfile', 'param-file' : 'paramfile', 'run-obj' : 'run_obj', 'run-objective' : 'run_obj', 'runObj' : 'run_obj', 'overall_obj' : 'overall_obj', 'intra-obj' : 'overall_obj', 'intra-instance-obj' : 'overall_obj', 'overall-obj' : 'overall_obj', 'intraInstanceObj' : 'overall_obj', 'overallObj' : 'overall_obj', 'intra_instance_obj' : 'overall_obj', 'algo-cutoff-time' : 'cutoff_time', 'target-run-cputime-limit' : 'cutoff_time', 'target_run_cputime_limit' : 'cutoff_time', 'cutoff-time' : 'cutoff_time', 'cutoffTime' : 'cutoff_time', 'cputime-limit' : 'tunerTimeout', 'cputime_limit' : 'tunerTimeout', 'tunertime-limit' : 'tunerTimeout', 'tuner-timeout' : 'tunerTimeout', 'tunerTimeout' : 'tunerTimeout', 'wallclock_limit' : 'wallclock-limit', 'runtime-limit' : 'wallclock-limit', 'runtimeLimit' : 'wallclock-limit', 'wallClockLimit' : 'wallclock-limit', 'output-dir' : 'outdir', 'outputDirectory' : 'outdir', 'instances' : 'instance_file', 'instance-file' : 'instance_file' , 'instance-dir' : 'instance_file', 'instanceFile' : 'instance_file', 'i' : 'instance_file', 'instance_seed_file' : 'instance_file', 'test-instances' : 'test_instance_file', 'test-instance-file' : 'test_instance_file', 'test-instance-dir' : 'test_instance_file', 'testInstanceFile' : 'test_instance_file', 'test_instance_file' : 'test_instance_file', 'test_instance_seed_file' : 'test_instance_file', 'feature-file' : 'feature_file', 'instanceFeatureFile' : 'feature_file', 'feature_file' : 'feature_file' } scenario_dict = {} with open(fn, 'r') as fh: for line in fh.readlines(): #remove comments if line.find("#") > -1: line = line[:line.find("#")] # skip empty lines if line == "": continue if "=" in line: tmp = line.split("=") tmp = [' '.join(s.split()) for s in tmp] else: tmp = line.split() scenario_dict[scenario_option_names.get(tmp[0],tmp[0])] = " ".join(tmp[1:]) return(scenario_dict)