Пример #1
0
 def test_upgrade():
     temp_dir = tempfile.mkdtemp(prefix='switch_test_')
     example_name = os.path.basename(os.path.normpath(example_dir))
     upgrade_dir = os.path.join(temp_dir, example_name)
     shutil.copytree(example_dir, upgrade_dir, ignore=shutil.ignore_patterns('outputs'))
     upgrade_dir_inputs = os.path.join(upgrade_dir, 'inputs')
     upgrade_dir_outputs = os.path.join(upgrade_dir, 'outputs')
     switch_model.upgrade.manager.set_verbose(False)
     try:
         # Custom python modules may be in the example's working directory
         upgrade_inputs(upgrade_dir_inputs)
         sys.path.append(upgrade_dir)
         switch_model.solve.main([
             '--inputs-dir', upgrade_dir_inputs,
             '--outputs-dir', upgrade_dir_outputs])
         total_cost = read_file(os.path.join(upgrade_dir_outputs, 'total_cost.txt'))
     finally:
         if upgrade_dir in sys.path: # code above may have failed before appending
             sys.path.remove(upgrade_dir)
         _remove_temp_dir(temp_dir)
     expectation_file = get_expectation_path(example_dir)
     if UPDATE_EXPECTATIONS:
         write_file(expectation_file, total_cost)
     else:
         expected = float(read_file(expectation_file))
         actual = float(total_cost)
         if not switch_model.utilities.approx_equal(expected, actual,
                                                  tolerance=0.0001):
             raise AssertionError(
                 'Mismatch for total_cost (the objective function value):\n'
                 'Expected value:  {}\n'
                 'Actual value:    {}\n'
                 'Run "python -m tests.upgrade_test --update" to '
                 'update the expectations if this change is expected.'
                 .format(expected, actual))
Пример #2
0
def main(args=None, return_model=False, return_instance=False):

    timer = StepTimer()
    if args is None:
        # combine default arguments read from options.txt file with
        # additional arguments specified on the command line
        args = get_option_file_args(extra_args=sys.argv[1:])

    # Get options needed before any modules are loaded
    pre_module_options = parse_pre_module_options(args)

    # turn on post-mortem debugging mode if requested
    # (from http://stackoverflow.com/a/1237407 ; more options available there)
    if pre_module_options.debug:
        def debug(type, value, tb):
            import traceback
            try:
                from ipdb import pm
            except ImportError:
                from pdb import pm
            traceback.print_exception(type, value, tb)
            pm()
        sys.excepthook = debug

    # Write output to a log file if logging option is specified
    if pre_module_options.log_run_to_file:
        logs_dir = pre_module_options.logs_dir
    else:
        logs_dir = None # disables logging

    with LogOutput(logs_dir):

        # Look out for outdated inputs. This has to happen before modules.txt is
        # parsed to avoid errors from incompatible files.
        parser = _ArgumentParser(allow_abbrev=False, add_help=False)
        add_module_args(parser)
        module_options = parser.parse_known_args(args=args)[0]
        if(os.path.exists(module_options.inputs_dir) and
           do_inputs_need_upgrade(module_options.inputs_dir)):
            do_upgrade = query_yes_no(
                "Warning! Your inputs directory needs to be upgraded. "
                "Do you want to auto-upgrade now? We'll keep a backup of "
                "this current version."
            )
            if do_upgrade:
                upgrade_inputs(module_options.inputs_dir)
            else:
                print("Inputs need upgrade. Consider `switch upgrade --help`. Exiting.")
                stop_logging_output()
                return -1

        # build a module list based on configuration options, and add
        # the current module (to register define_arguments callback)
        modules = get_module_list(args)

        # Patch pyomo if needed, to allow reconstruction of expressions.
        # This must be done before the model is constructed.
        patch_pyomo()

        # Define the model
        model = create_model(modules, args=args)

        # Add any suffixes specified on the command line (usually only iis)
        add_extra_suffixes(model)

        # return the model as-is if requested
        if return_model and not return_instance:
            return model

        if model.options.reload_prior_solution:
            # TODO: allow a directory to be specified after --reload-prior-solution,
            # otherwise use outputs_dir.
            if not os.path.isdir(model.options.outputs_dir):
                raise IOError("Directory specified for prior solution does not exist.")

        # get a list of modules to iterate through
        iterate_modules = get_iteration_list(model)

        if model.options.verbose:
            print("\n=======================================================================")
            print("Switch {}, http://switch-model.org".format(switch_model.__version__))
            print("=======================================================================")
            print("Arguments:")
            print(", ".join(k+"="+repr(v) for k, v in model.options.__dict__.items() if v))
            print("Modules:\n"+", ".join(m for m in modules))
            if iterate_modules:
                print("Iteration modules:", iterate_modules)
            print("=======================================================================\n")
            print("Model created in {:.2f} s.".format(timer.step_time()))
            print("Loading inputs...")

        # create an instance (also reports time spent reading data and loading into model)
        instance = model.load_inputs()

        #### Below here, we refer to instance instead of model ####

        instance.pre_solve()
        if instance.options.verbose:
            print("Total time spent constructing model: {:.2f} s.\n".format(timer.step_time()))

        # return the instance as-is if requested
        if return_instance:
            if return_model:
                return (model, instance)
            else:
                return instance

        # make sure the outputs_dir exists (used by some modules during iterate)
        # use a race-safe approach in case this code is run in parallel
        try:
            os.makedirs(instance.options.outputs_dir)
        except OSError:
            # directory probably exists already, but double-check
            if not os.path.isdir(instance.options.outputs_dir):
                raise

        if instance.options.reload_prior_solution:
            print('Loading prior solution...')
            reload_prior_solution_from_pickle(instance, instance.options.outputs_dir)
            if instance.options.verbose:
                print(
                    'Loaded previous results into model instance in {:.2f} s.'
                    .format(timer.step_time())
                )
        else:
            # solve the model (reports time for each step as it goes)
            if iterate_modules:
                if instance.options.verbose:
                    print("Iterating model...")
                iterate(instance, iterate_modules)
            else:
                results = solve(instance)
                if instance.options.verbose:
                    print("")
                    print("Optimization termination condition was {}.".format(
                        results.solver.termination_condition))
                    if str(results.solver.message) != '<undefined>':
                        print('Solver message: {}'.format(results.solver.message))
                    print("")

                if instance.options.verbose:
                    timer.step_time() # restart counter for next step

                if not instance.options.no_save_solution:
                    save_results(instance, instance.options.outputs_dir)
                    if instance.options.verbose:
                        print('Saved results in {:.2f} s.'.format(timer.step_time()))

        # report results
        # (repeated if model is reloaded, to automatically run any new export code)
        if not instance.options.no_post_solve:
            if instance.options.verbose:
                print("Executing post solve functions...")
            instance.post_solve()
            if instance.options.verbose:
                print("Post solve processing completed in {:.2f} s.".format(timer.step_time()))

    # end of LogOutput block

    if instance.options.interact:
        m = instance  # present the solved model as 'm' for convenience
        banner = (
            "\n"
            "=======================================================================\n"
            "Entering interactive Python shell.\n"
            "Abstract model is in 'model' variable; \n"
            "Solved instance is in 'instance' and 'm' variables.\n"
            "Type ctrl-d or exit() to exit shell.\n"
            "=======================================================================\n"
        )
        import code
        code.interact(banner=banner, local=dict(list(globals().items()) + list(locals().items())))
Пример #3
0
def main(args=None, return_model=False, return_instance=False):

    timer = StepTimer()
    if args is None:
        # combine default arguments read from options.txt file with
        # additional arguments specified on the command line
        args = get_option_file_args(extra_args=sys.argv[1:])

    # Get options needed before any modules are loaded
    pre_module_options = parse_pre_module_options(args)

    # turn on post-mortem debugging mode if requested
    # (from http://stackoverflow.com/a/1237407 ; more options available there)
    if pre_module_options.debug:
        def debug(type, value, tb):
            import traceback, pdb
            traceback.print_exception(type, value, tb)
            pdb.pm()
        sys.excepthook = debug

    # Write output to a log file if logging option is specified
    if pre_module_options.log_run_to_file:
        logs_dir = pre_module_options.logs_dir
    else:
        logs_dir = None # disables logging

    with LogOutput(logs_dir):

        # Look out for outdated inputs. This has to happen before modules.txt is
        # parsed to avoid errors from incompatible files.
        parser = _ArgumentParser(allow_abbrev=False, add_help=False)
        add_module_args(parser)
        module_options = parser.parse_known_args(args=args)[0]
        if(os.path.exists(module_options.inputs_dir) and
           do_inputs_need_upgrade(module_options.inputs_dir)):
            do_upgrade = query_yes_no(
                ("Warning! Your inputs directory needs to be upgraded. "
                 "Do you want to auto-upgrade now? We'll keep a backup of "
                 "this current version."))
            if do_upgrade:
                upgrade_inputs(module_options.inputs_dir)
            else:
                print "Inputs need upgrade. Consider `switch upgrade --help`. Exiting."
                stop_logging_output()
                return -1

        # build a module list based on configuration options, and add
        # the current module (to register define_arguments callback)
        modules = get_module_list(args)

        # Patch pyomo if needed, to allow reconstruction of expressions.
        # This must be done before the model is constructed.
        patch_pyomo()

        # Define the model
        model = create_model(modules, args=args)

        # Add any suffixes specified on the command line (usually only iis)
        add_extra_suffixes(model)

        # return the model as-is if requested
        if return_model and not return_instance:
            return model

        if model.options.reload_prior_solution:
            # TODO: allow a directory to be specified after --reload-prior-solution,
            # otherwise use outputs_dir.
            if not os.path.isdir(model.options.outputs_dir):
                raise IOError("Directory specified for prior solution does not exist.")

        # get a list of modules to iterate through
        iterate_modules = get_iteration_list(model)

        if model.options.verbose:
            print "\n======================================================================="
            print "SWITCH model created in {:.2f} s.\nArguments:".format(timer.step_time())
            print ", ".join(k+"="+repr(v) for k, v in model.options.__dict__.items() if v)
            print "Modules:\n"+", ".join(m for m in modules)
            if iterate_modules:
                print "Iteration modules:", iterate_modules
            print "=======================================================================\n"
            print "Loading inputs..."

        # create an instance (also reports time spent reading data and loading into model)
        instance = model.load_inputs()

        #### Below here, we refer to instance instead of model ####

        instance.pre_solve()
        if instance.options.verbose:
            print "Total time spent constructing model: {:.2f} s.\n".format(timer.step_time())

        # return the instance as-is if requested
        if return_instance:
            if return_model:
                return (model, instance)
            else:
                return instance

        # make sure the outputs_dir exists (used by some modules during iterate)
        # use a race-safe approach in case this code is run in parallel
        try:
            os.makedirs(instance.options.outputs_dir)
        except OSError:
            # directory probably exists already, but double-check
            if not os.path.isdir(instance.options.outputs_dir):
                raise

        if instance.options.reload_prior_solution:
            print('Loading prior solution...')
            reload_prior_solution_from_pickle(instance, instance.options.outputs_dir)
            if instance.options.verbose:
                print(
                    'Loaded previous results into model instance in {:.2f} s.'
                    .format(timer.step_time())
                )
        else:
            # solve the model (reports time for each step as it goes)
            if iterate_modules:
                if instance.options.verbose:
                    print "Iterating model..."
                iterate(instance, iterate_modules)
            else:
                results = solve(instance)
                if instance.options.verbose:
                    print ""
                    print results.solver.message
                    print "Optimization termination condition was {}.".format(
                        results.solver.termination_condition)
                    print ""

                if instance.options.verbose:
                    timer.step_time() # restart counter for next step

                if not instance.options.no_save_solution:
                    save_results(instance, instance.options.outputs_dir)
                    if instance.options.verbose:
                        print('Saved results in {:.2f} s.'.format(timer.step_time()))

        # report results
        # (repeated if model is reloaded, to automatically run any new export code)
        if not instance.options.no_post_solve:
            if instance.options.verbose:
                print "Executing post solve functions..."
            instance.post_solve()
            if instance.options.verbose:
                print "Post solve processing completed in {:.2f} s.".format(timer.step_time())

    # end of LogOutput block

    if instance.options.interact:
        m = instance  # present the solved model as 'm' for convenience
        banner = (
            "\n"
            "=======================================================================\n"
            "Entering interactive Python shell.\n"
            "Abstract model is in 'model' variable; \n"
            "Solved instance is in 'instance' and 'm' variables.\n"
            "Type ctrl-d or exit() to exit shell.\n"
            "=======================================================================\n"
        )
        import code
        code.interact(banner=banner, local=dict(globals().items() + locals().items()))
Пример #4
0
def main(args=None, return_model=False, return_instance=False):

    start_time = time.time()
    if args is None:
        # combine default arguments read from options.txt file with 
        # additional arguments specified on the command line
        args = get_option_file_args(extra_args=sys.argv[1:])

    # Get options needed before any modules are loaded
    pre_module_options = parse_pre_module_options(args)
    
    # turn on post-mortem debugging mode if requested
    # (from http://stackoverflow.com/a/1237407 ; more options available there)
    if pre_module_options.debug:
        def debug(type, value, tb):
            import traceback, pdb
            traceback.print_exception(type, value, tb)
            pdb.pm()
        sys.excepthook = debug

    # Write output to a log file if logging option is specified
    stdout_copy = sys.stdout  # make a copy of current sys.stdout to return to eventually

    if pre_module_options.log_run_to_file:
        logging = Logging(pre_module_options.logs_dir)
        print "logging run to " + str(logging.log_file_path)
        sys.stdout = logging  # assign private class to sys.stdout
    else:
        pass

    # Look out for outdated inputs. This has to happen before modules.txt is
    # parsed to avoid errors from incompatible files.
    parser = _ArgumentParser(allow_abbrev=False, add_help=False)
    add_module_args(parser)
    module_options = parser.parse_known_args(args=args)[0]
    if(os.path.exists(module_options.inputs_dir) and
       do_inputs_need_upgrade(module_options.inputs_dir)):
        do_upgrade = query_yes_no(
            ("Warning! Your inputs directory needs to be upgraded. "
             "Do you want to auto-upgrade now? We'll keep a backup of "
             "this current version."))
        if do_upgrade:
            upgrade_inputs(module_options.inputs_dir)
        else:
            print "Inputs need upgrade. Consider `switch upgrade --help`. Exiting."
            sys.stdout = stdout_copy
            return -1

    # build a module list based on configuration options, and add
    # the current module (to register define_arguments callback)
    modules = get_module_list(args)
    
    # Patch pyomo if needed, to allow reconstruction of expressions.
    # This must be done before the model is constructed.
    patch_pyomo()

    # Define the model
    model = create_model(modules, args=args)

    # Add any suffixes specified on the command line (usually only iis)
    add_extra_suffixes(model)
    
    # return the model as-is if requested
    if return_model and not return_instance:
        return model

    if model.options.reload_prior_solution:
        if not os.path.isdir(model.options.outputs_dir):
            raise IOError("Specified outputs directory for solution exploration does not exist.")

    # get a list of modules to iterate through
    iterate_modules = get_iteration_list(model)
    
    if model.options.verbose:
        creation_time = time.time()
        print "\n======================================================================="
        print "SWITCH model created in {:.2f} s.\nArguments:".format(creation_time - start_time)
        print ", ".join(k+"="+repr(v) for k, v in model.options.__dict__.items() if v)
        print "Modules:\n"+", ".join(m for m in modules)
        if iterate_modules:
            print "Iteration modules:", iterate_modules
        print "=======================================================================\n"
        print "Loading inputs..."

    # create an instance
    instance = model.load_inputs()
    instance.pre_solve()
    instantiation_time = time.time()
    if model.options.verbose:
        print "Inputs loaded in {:.2f} s.\n".format(instantiation_time - creation_time)
    
    # return the instance as-is if requested
    if return_instance:
        if return_model:
            return (model, instance)
        else:
            return instance

    if model.options.reload_prior_solution:
        # read variable values from previously solved model
        import csv
        var_objects = [c for c in instance.component_objects()
            if isinstance(c,pyomo.core.base.Var)]
        def _convert_if_numeric(s):
            try:
                return float(s)
            except ValueError:
                return s
        for var in var_objects:
            if '{}.tab'.format(var.name) not in os.listdir(model.options.outputs_dir):
                raise RuntimeError("Tab output file for variable {} cannot be found in outputs directory. Exiting.".format(var.name))
            with open(os.path.join(model.options.outputs_dir, '{}.tab'.format(var.name)),'r') as f:
                reader = csv.reader(f, delimiter='\t')
                # skip headers
                next(reader)
                for row in reader:
                    index = (_convert_if_numeric(i) for i in row[:-1])
                    var[index].value = float(row[-1])
            print 'Loaded variable {} values into instance.'.format(var.name)
        output_loading_time = time.time()
        print 'Finished loading previous results into model instance in {:.2f} s.'.format(output_loading_time - instantiation_time)
    else:
        # make sure the outputs_dir exists (used by some modules during iterate)
        # use a race-safe approach in case this code is run in parallel
        try:
            os.makedirs(model.options.outputs_dir)
        except OSError:
            # directory probably exists already, but double-check
            if not os.path.isdir(model.options.outputs_dir):
                raise

        # solve the model
        if iterate_modules:
            if model.options.verbose:
                print "Iterating model..."
            iterate(instance, iterate_modules)
        else:
            results = solve(instance)
            if model.options.verbose:
                print "Optimization termination condition was {}.\n".format(
                    results.solver.termination_condition)

        # report/save results
        if model.options.verbose:
            post_solve_start_time = time.time()
            print "Executing post solve functions..."
        instance.post_solve()
        if model.options.verbose:
            post_solve_end_time = time.time()
            print "Post solve processing completed in {:.2f} s.".format(
                post_solve_end_time - post_solve_start_time)

    # return stdout to original
    sys.stdout = stdout_copy

    if model.options.interact or model.options.reload_prior_solution:
        m = instance  # present the solved model as 'm' for convenience
        banner = (
            "\n"
            "=======================================================================\n"
            "Entering interactive Python shell.\n"
            "Abstract model is in 'model' variable; \n"
            "Solved instance is in 'instance' and 'm' variables.\n"
            "Type ctrl-d or exit() to exit shell.\n"
            "=======================================================================\n"
        )
        import code
        code.interact(banner=banner, local=dict(globals().items() + locals().items()))
Пример #5
0
def main(args=None, return_model=False, return_instance=False):

    start_time = time.time()
    if args is None:
        # combine default arguments read from options.txt file with
        # additional arguments specified on the command line
        args = get_option_file_args(extra_args=sys.argv[1:])

    # Get options needed before any modules are loaded
    pre_module_options = parse_pre_module_options(args)

    # turn on post-mortem debugging mode if requested
    # (from http://stackoverflow.com/a/1237407 ; more options available there)
    if pre_module_options.debug:

        def debug(type, value, tb):
            import traceback, pdb
            traceback.print_exception(type, value, tb)
            pdb.pm()

        sys.excepthook = debug

    # Write output to a log file if logging option is specified
    stdout_copy = sys.stdout  # make a copy of current sys.stdout to return to eventually

    if pre_module_options.log_run_to_file:
        logging = Logging(pre_module_options.logs_dir)
        print "logging run to " + str(logging.log_file_path)
        sys.stdout = logging  # assign private class to sys.stdout
    else:
        pass

    # Look out for outdated inputs. This has to happen before modules.txt is
    # parsed to avoid errors from incompatible files.
    parser = _ArgumentParser(allow_abbrev=False, add_help=False)
    add_module_args(parser)
    module_options = parser.parse_known_args(args=args)[0]
    if (os.path.exists(module_options.inputs_dir)
            and do_inputs_need_upgrade(module_options.inputs_dir)):
        do_upgrade = query_yes_no(
            ("Warning! Your inputs directory needs to be upgraded. "
             "Do you want to auto-upgrade now? We'll keep a backup of "
             "this current version."))
        if do_upgrade:
            upgrade_inputs(module_options.inputs_dir)
        else:
            print "Inputs need upgrade. Consider `switch upgrade --help`. Exiting."
            sys.stdout = stdout_copy
            return -1

    # build a module list based on configuration options, and add
    # the current module (to register define_arguments callback)
    modules = get_module_list(args)

    # Patch pyomo if needed, to allow reconstruction of expressions.
    # This must be done before the model is constructed.
    patch_pyomo()

    # Define the model
    model = create_model(modules, args=args)

    # Add any suffixes specified on the command line (usually only iis)
    add_extra_suffixes(model)

    # return the model as-is if requested
    if return_model and not return_instance:
        return model

    if model.options.reload_prior_solution:
        if not os.path.isdir(model.options.outputs_dir):
            raise IOError(
                "Specified outputs directory for solution exploration does not exist."
            )

    # get a list of modules to iterate through
    iterate_modules = get_iteration_list(model)

    if model.options.verbose:
        creation_time = time.time()
        print "\n======================================================================="
        print "SWITCH model created in {:.2f} s.\nArguments:".format(
            creation_time - start_time)
        print ", ".join(k + "=" + repr(v)
                        for k, v in model.options.__dict__.items() if v)
        print "Modules:\n" + ", ".join(m for m in modules)
        if iterate_modules:
            print "Iteration modules:", iterate_modules
        print "=======================================================================\n"
        print "Loading inputs..."

    # create an instance
    instance = model.load_inputs()
    instance.pre_solve()
    instantiation_time = time.time()
    if model.options.verbose:
        print "Inputs loaded in {:.2f} s.\n".format(instantiation_time -
                                                    creation_time)

    #Paty's addition for debugging:
    #embed()

    # return the instance as-is if requested
    if return_instance:
        if return_model:
            return (model, instance)
        else:
            return instance

    if model.options.reload_prior_solution:
        # read variable values from previously solved model
        import csv
        var_objects = [
            c for c in instance.component_objects()
            if isinstance(c, pyomo.core.base.Var)
        ]

        def _convert_if_numeric(s):
            try:
                return float(s)
            except ValueError:
                return s

        for var in var_objects:
            if '{}.tab'.format(var.name) not in os.listdir(
                    model.options.outputs_dir):
                raise RuntimeError(
                    "Tab output file for variable {} cannot be found in outputs directory. Exiting."
                    .format(var.name))
            with open(
                    os.path.join(model.options.outputs_dir,
                                 '{}.tab'.format(var.name)), 'r') as f:
                reader = csv.reader(f, delimiter='\t')
                # skip headers
                next(reader)
                for row in reader:
                    index = (_convert_if_numeric(i) for i in row[:-1])
                    var[index].value = float(row[-1])
            print 'Loaded variable {} values into instance.'.format(var.name)
        output_loading_time = time.time()
        print 'Finished loading previous results into model instance in {:.2f} s.'.format(
            output_loading_time - instantiation_time)
    else:
        # make sure the outputs_dir exists (used by some modules during iterate)
        # use a race-safe approach in case this code is run in parallel
        try:
            os.makedirs(model.options.outputs_dir)
        except OSError:
            # directory probably exists already, but double-check
            if not os.path.isdir(model.options.outputs_dir):
                raise

        # solve the model
        if iterate_modules:
            if model.options.verbose:
                print "Iterating model..."
            iterate(instance, iterate_modules)
        else:
            results = solve(instance)
            if model.options.verbose:
                print "Optimization termination condition was {}.\n".format(
                    results.solver.termination_condition)

#Paty's addition for debugging:
#embed()

# report/save results
        if model.options.verbose:
            post_solve_start_time = time.time()
            print "Executing post solve functions..."
        instance.post_solve()
        if model.options.verbose:
            post_solve_end_time = time.time()
            print "Post solve processing completed in {:.2f} s.".format(
                post_solve_end_time - post_solve_start_time)

    # return stdout to original
    sys.stdout = stdout_copy

    if model.options.interact or model.options.reload_prior_solution:
        m = instance  # present the solved model as 'm' for convenience
        banner = (
            "\n"
            "=======================================================================\n"
            "Entering interactive Python shell.\n"
            "Abstract model is in 'model' variable; \n"
            "Solved instance is in 'instance' and 'm' variables.\n"
            "Type ctrl-d or exit() to exit shell.\n"
            "=======================================================================\n"
        )
        import code
        code.interact(banner=banner,
                      local=dict(globals().items() + locals().items()))