示例#1
0
def benchmark(mst_binary, input_graph, out, rev, trial_num, for_time):
    rel_input_graph = ppinput(input_graph)
    if not print_benchmark(rel_input_graph, out, rev, trial_num, for_time):
        trial_num = -1  # cancel logging

    # determine how to save the output
    kill_out = False
    if for_time or out != '/dev/null':
        # disable /dev/null for performance experiments so we can get the weight for now ...
        if out == '/dev/null':
            out = random_tmp_filename(10, 'weight-for-time')
            kill_out = True

        save_cmd = '> ' + out
    else:
        # save just the first line of output so we can get the weight
        out = random_tmp_filename(10, 'weight')
        save_cmd = '| head -n 1 > ' + out
        kill_out = True

    # run mst (and time it)
    time_file = random_tmp_filename(10, 'time')
    cmd = '/usr/bin/time -f %%U -o %s %s %s %s' % (time_file, mst_binary,
                                                   input_graph, save_cmd)
    ret = os.system(cmd)
    if ret != 0:
        print >> sys.stderr, "mst exited with error: " + cmd
        quiet_remove(time_file)
        return
    try:
        time_sec = extract_answer(time_file)
    except CheckerError, e:
        print >> sys.stderr, "failed to read time file: " + str(e)
        return
示例#2
0
def benchmark(mst_binary, input_graph, out, rev, trial_num, for_time):
    rel_input_graph = ppinput(input_graph)
    if not print_benchmark(rel_input_graph, out, rev, trial_num, for_time):
        trial_num = -1  # cancel logging

    # determine how to save the output
    kill_out = False
    if for_time or out != '/dev/null':
        # disable /dev/null for performance experiments so we can get the weight for now ...
        if out == '/dev/null':
            out = random_tmp_filename(10, 'weight-for-time')
            kill_out = True

        save_cmd = '> ' + out
    else:
        # save just the first line of output so we can get the weight
        out = random_tmp_filename(10, 'weight')
        save_cmd = '| head -n 1 > ' + out
        kill_out = True

    # run mst (and time it)
    time_file = random_tmp_filename(10, 'time')
    cmd = '/usr/bin/time -f %%U -o %s %s %s %s' % (time_file, mst_binary, input_graph, save_cmd)
    ret = os.system(cmd)
    if ret != 0:
        print >> sys.stderr, "mst exited with error: " + cmd
        quiet_remove(time_file)
        return
    try:
        time_sec = extract_answer(time_file)
    except CheckerError, e:
        print >> sys.stderr, "failed to read time file: " + str(e)
        return
示例#3
0
def __compute_mst_weight(input_graph, corr_file):
    """Internal method to actual compute the MST weight of input_graph"""
    checker = get_path_to_checker_binary(True)
    ret = os.system('%s %s > %s' % (checker, input_graph, corr_file))
    if ret == 0:
        return extract_answer(corr_file)
    else:
        raise CheckerError("checker error: failed to generate output for " + ppinput(input_graph))
示例#4
0
def __get_ti(input_graph):
    try:
        return extract_input_footer(input_graph)
    except ExtractInputFooterError, e:
        raise CheckerError("checker error: unable to extract the input footer for %s: %s" % (ppinput(input_graph), e))
示例#5
0
        outcome = INCORRECT

    if ans_out is not None:
        (ti, ans_corr) = get_and_log_mst_weight_from_checker(input_graph, force_recompute, inputslogfn)
    else:
        ti = None

    # are they the same?
    if ans_out is not None:
        fmt = '%.' + str(tolerance) + 'f'
        str_ans_corr = fmt % ans_corr
        str_ans_out = fmt % ans_out
        if str_ans_corr == str_ans_out:
            outcome = CORRECT
        else:
            print >> sys.stderr, "correctness FAILED: %s (correct is %s, output had %s)" % (ppinput(input_graph), str_ans_corr, str_ans_out)
            outcome = INCORRECT

    # log the result of the correctness check
    if rev is not None and run is not None:
        if ti is None:
            ti = __get_ti(input_graph)

        data = CorrResult(ti.dims, ti.min, ti.max, ti.num_verts, ti.num_edges, ti.seed, rev, run, outcome)
        try:
            DataSet.add_data_to_log_file(data)
            print 'logged correctness result to ' + data.get_path()
        except DataError, e:
            fmt = "Unable to log result to file %s (correct is %s, output had %s): %s"
            print >> sys.stderr, fmt % (ppinput(input_graph), str_ans_corr, str_ans_out, e)
示例#6
0
def main(argv=sys.argv[1:],
         get_output_name_only=False,
         get_is_for_part2=False):
    usage = """usage: %prog [options] NUM_VERTICES
Generates a connected graph with no self-loops or parallel edges.  Output is
sent to the default filename (""" + get_path_to_generated_inputs() + """/with
V-E-SEED.g unless -e or -v are specified in which case a random filename is
used.)"""
    parser = OptionParser(usage)
    parser.add_option("-c",
                      "--correctness",
                      action="store_true",
                      default=False,
                      help="compute and log the correct output")
    parser.add_option(
        "-d",
        "--dont-generate",
        action="store_true",
        default=False,
        help="add the input to the inputs list file but do not generate it")
    parser.add_option(
        "-l",
        "--inputs-list-file",
        metavar="FILE",
        help=
        "set the file to store info about the new input to (default is usually fine)"
    )
    parser.add_option(
        "-m",
        "--may-use-existing",
        action="store_true",
        default=False,
        help="will not generate a new graph if the output file already exists")
    parser.add_option(
        "-n",
        "--num-edges",
        help="number of edges to put in the graph [default: complete graph]")
    parser.add_option(
        "-o",
        "--output-file",
        help=
        "where to output the generated graph [default is inputs/[<STYLE>-]<NUM_VERTICES>-<NUM_EDGES>-<RANDOM_SEED>.g"
    )
    parser.add_option(
        "-p",
        "--precision",
        type="int",
        default=1,
        help=
        "number of decimal points to specify for edge weights [default: %default]"
    )
    parser.add_option("-q",
                      "--quiet",
                      action="store_true",
                      default=False,
                      help="do not log any extraneous information to stdout")
    parser.add_option(
        "-r",
        "--random-seed",
        metavar="R",
        type="int",
        default=None,
        help=
        "what random seed to use [default: choose a truly random seed using urandom()]"
    )
    parser.add_option(
        "-s",
        "--style",
        help=
        "how to place edges [default: random with no self-loops or parallel edges]"
    )
    parser.add_option(
        "-t",
        "--dont-track",
        action="store_true",
        default=False,
        help="whether to log this input in our list of generated inputs")

    group = OptionGroup(parser, "Generation Type Options")
    group.add_option(
        "-e",
        "--edge-weight-range",
        metavar="MIN,MAX",
        help="range of edge weights (range inclusive) [default: [0.1,100000]]")
    group.add_option(
        "-v",
        "--vertex-pos-range",
        metavar="DIM,MIN,MAX",
        help=
        "dimensionality of vertex positions and the range of each dimension (range inclusive) [not used by default; mutually exclusive with -e]"
    )
    parser.add_option_group(group)

    (options, args) = parser.parse_args(argv)
    if len(args) < 1:
        parser.error("missing NUM_VERTICES")
    elif len(args) > 1:
        parser.error("too many arguments")

    # make sure --dont-generate isn't specified along with mutex switches
    if options.dont_generate:
        if options.correctness:
            parser.error('-c cannot be specified with --dont-generate')
        if options.dont_track:
            parser.error('-t cannot be specified with --dont-generate')
        if options.output_file:
            parser.error('-o cannot be specified with --dont-generate')

    # just return whether the input specified would be for part 2
    if get_is_for_part2:
        return options.edge_weight_range is not None or options.vertex_pos_range is not None

    # initialize the random number generator
    global __RND_SEED
    global __rnd
    if options.random_seed is not None:
        __RND_SEED = options.random_seed
    else:
        __RND_SEED = unpack(
            'Q', urandom(8))[0]  # generate a truly random 8-byte seed
    __rnd = Random(__RND_SEED)

    def print_if_not_quiet(msg):
        if not options.quiet:
            print msg

    # determine how many vertices should be in the graph
    try:
        num_verts = int(args[0])
    except ValueError:
        parser.error("NUM_VERTICES must be an integer")

    try:
        sne = options.num_edges
        if sne == 'c' or sne == 'complete' or sne is None:
            num_edges = edges_in_complete_undirected_graph(num_verts)
        else:
            num_edges = int(sne)
            if num_edges > edges_in_complete_undirected_graph(num_verts):
                parser.error(
                    "-n may not be larger than NUM_VERTICES*(NUM_VERTICES-1)/2 (complete graph may not have self-loops or parallel edges)"
                )
            elif num_edges < num_verts - 1:
                parser.error(
                    "-n may not be less than NUM_VERTICES-1 (graph must be connected)"
                )
    except ValueError:
        parser.error("-n must either be an integer or 'complete'")

    if options.precision <= 0:
        parser.error("-p must be at least 1")
    elif options.precision > 15:
        parser.error(
            "-p must be no more than 15 (doubles cannot accurately represent more than this)"
        )

    if options.style is not None:
        parser.error("option -s is not yet supported")
    else:
        style_str = ''

    if options.edge_weight_range and options.vertex_pos_range:
        parser.error("option -e and -v are mutually exclusive")

    # determine the output file to use
    if options.output_file is None:
        path = get_path_to_generated_inputs()
        if options.vertex_pos_range or options.edge_weight_range:
            options.output_file = path + 'other-' + str(__RND_SEED) + '.g'
        else:
            options.output_file = path + '%s%u-%u-%s.g' % (
                style_str, num_verts, num_edges, str(__RND_SEED))

    # special use of the method ... just return the name we would use
    if get_output_name_only:
        return options.output_file

    # open the desired output file
    if options.output_file == 'stdout':
        out = sys.stdout
    elif not options.dont_generate:
        if options.may_use_existing:
            if os.path.exists(options.output_file):
                print_if_not_quiet(
                    'skipping input generation: %s already exists' %
                    ppinput(options.output_file))
                return 0
        try:
            out = open(options.output_file, 'w')
        except IOError, errstr:
            die('generate_input: error: ' + errstr)
示例#7
0
                           (str(get_density(num_verts, num_edges)),
                            str(get_percent_of_max(num_verts, num_edges))))
        if not options.dont_generate:
            about = gen_random_edge_lengths(num_verts, num_edges, min_edge_len,
                                            max_edge_len, options.precision,
                                            out)
        dimensionality = 0
        min_val = min_edge_len
        max_val = max_edge_len

    mst_weight = -1
    if options.dont_generate:
        print_if_not_quiet('graph not saved (as requested)')
    else:
        print_input_footer(num_verts, num_edges, about, out)
        print_if_not_quiet('graph saved to ' + ppinput(options.output_file))
        if out != sys.stdout:
            out.close()

        # generate output with correctness checker, if desired
        if options.correctness:
            if options.dont_track:
                print >> sys.stderr, "warning: skipping correctness output (only done when -t is not specified)"
                return 0
            try:
                mst_weight = compute_mst_weight(options.output_file)
            except CheckerError, e:
                print >> sys.stderr, e

    # record this new input in our input log
    if not options.dont_track:
示例#8
0
def main(argv=sys.argv[1:], get_output_name_only=False, get_is_for_part2=False):
    usage = """usage: %prog [options] NUM_VERTICES
Generates a connected graph with no self-loops or parallel edges.  Output is
sent to the default filename (""" + get_path_to_generated_inputs() + """/with
V-E-SEED.g unless -e or -v are specified in which case a random filename is
used.)"""
    parser = OptionParser(usage)
    parser.add_option("-c", "--correctness",
                      action="store_true", default=False,
                      help="compute and log the correct output")
    parser.add_option("-d", "--dont-generate",
                      action="store_true", default=False,
                      help="add the input to the inputs list file but do not generate it")
    parser.add_option("-l", "--inputs-list-file",
                      metavar="FILE",
                      help="set the file to store info about the new input to (default is usually fine)")
    parser.add_option("-m", "--may-use-existing",
                      action="store_true", default=False,
                      help="will not generate a new graph if the output file already exists")
    parser.add_option("-n", "--num-edges",
                      help="number of edges to put in the graph [default: complete graph]")
    parser.add_option("-o", "--output-file",
                      help="where to output the generated graph [default is inputs/[<STYLE>-]<NUM_VERTICES>-<NUM_EDGES>-<RANDOM_SEED>.g")
    parser.add_option("-p", "--precision",
                      type="int", default=1,
                      help="number of decimal points to specify for edge weights [default: %default]")
    parser.add_option("-q", "--quiet",
                      action="store_true", default=False,
                      help="do not log any extraneous information to stdout")
    parser.add_option("-r", "--random-seed",
                      metavar="R", type="int", default=None,
                      help="what random seed to use [default: choose a truly random seed using urandom()]")
    parser.add_option("-s", "--style",
                      help="how to place edges [default: random with no self-loops or parallel edges]")
    parser.add_option("-t", "--dont-track",
                      action="store_true", default=False,
                      help="whether to log this input in our list of generated inputs")

    group = OptionGroup(parser, "Generation Type Options")
    group.add_option("-e", "--edge-weight-range",
                     metavar="MIN,MAX",
                     help="range of edge weights (range inclusive) [default: [0.1,100000]]")
    group.add_option("-v", "--vertex-pos-range",
                     metavar="DIM,MIN,MAX",
                     help="dimensionality of vertex positions and the range of each dimension (range inclusive) [not used by default; mutually exclusive with -e]")
    parser.add_option_group(group)

    (options, args) = parser.parse_args(argv)
    if len(args) < 1:
        parser.error("missing NUM_VERTICES")
    elif len(args) > 1:
        parser.error("too many arguments")

    # make sure --dont-generate isn't specified along with mutex switches
    if options.dont_generate:
        if options.correctness:
            parser.error('-c cannot be specified with --dont-generate')
        if options.dont_track:
            parser.error('-t cannot be specified with --dont-generate')
        if options.output_file:
            parser.error('-o cannot be specified with --dont-generate')

    # just return whether the input specified would be for part 2
    if get_is_for_part2:
        return options.edge_weight_range is not None or options.vertex_pos_range is not None

    # initialize the random number generator
    global __RND_SEED
    global __rnd
    if options.random_seed is not None:
        __RND_SEED = options.random_seed
    else:
        __RND_SEED = unpack('Q', urandom(8))[0]  # generate a truly random 8-byte seed
    __rnd = Random(__RND_SEED)

    def print_if_not_quiet(msg):
        if not options.quiet:
            print msg

    # determine how many vertices should be in the graph
    try:
        num_verts = int(args[0])
    except ValueError:
        parser.error("NUM_VERTICES must be an integer")

    try:
        sne = options.num_edges
        if sne == 'c' or sne == 'complete' or sne is None:
            num_edges = edges_in_complete_undirected_graph(num_verts)
        else:
            num_edges = int(sne)
            if num_edges > edges_in_complete_undirected_graph(num_verts):
                parser.error("-n may not be larger than NUM_VERTICES*(NUM_VERTICES-1)/2 (complete graph may not have self-loops or parallel edges)")
            elif num_edges < num_verts - 1:
                parser.error("-n may not be less than NUM_VERTICES-1 (graph must be connected)")
    except ValueError:
        parser.error("-n must either be an integer or 'complete'")

    if options.precision <= 0:
        parser.error("-p must be at least 1")
    elif options.precision > 15:
        parser.error("-p must be no more than 15 (doubles cannot accurately represent more than this)")

    if options.style is not None:
        parser.error("option -s is not yet supported")
    else:
        style_str = ''

    if options.edge_weight_range and options.vertex_pos_range:
        parser.error("option -e and -v are mutually exclusive")

    # determine the output file to use
    if options.output_file is None:
        path = get_path_to_generated_inputs()
        if options.vertex_pos_range or options.edge_weight_range:
            options.output_file = path + 'other-' + str(__RND_SEED) + '.g'
        else:
            options.output_file = path + '%s%u-%u-%s.g' % (style_str, num_verts, num_edges, str(__RND_SEED))

    # special use of the method ... just return the name we would use
    if get_output_name_only:
        return options.output_file

    # open the desired output file
    if options.output_file == 'stdout':
        out = sys.stdout
    elif not options.dont_generate:
        if options.may_use_existing:
            if os.path.exists(options.output_file):
                print_if_not_quiet('skipping input generation: %s already exists' % ppinput(options.output_file))
                return 0
        try:
            out = open(options.output_file, 'w')
        except IOError, errstr:
            die('generate_input: error: ' + errstr)
示例#9
0
            min_edge_len = 0
            max_edge_len = 100000

        print_if_not_quiet('density=%s pom=%s' % (str(get_density(num_verts, num_edges)), str(get_percent_of_max(num_verts, num_edges))))
        if not options.dont_generate:
            about = gen_random_edge_lengths(num_verts, num_edges, min_edge_len, max_edge_len, options.precision, out)
        dimensionality = 0
        min_val = min_edge_len
        max_val = max_edge_len

    mst_weight = -1
    if options.dont_generate:
        print_if_not_quiet('graph not saved (as requested)')
    else:
        print_input_footer(num_verts, num_edges, about, out)
        print_if_not_quiet('graph saved to ' + ppinput(options.output_file))
        if out != sys.stdout:
            out.close()

        # generate output with correctness checker, if desired
        if options.correctness:
            if options.dont_track:
                print >> sys.stderr, "warning: skipping correctness output (only done when -t is not specified)"
                return 0
            try:
                mst_weight = compute_mst_weight(options.output_file)
            except CheckerError, e:
                print >> sys.stderr, e

    # record this new input in our input log
    if not options.dont_track: