import pyomo.environ as pyo from pyomo.common.timing import TicTocTimer from pyomo.core.expr.numeric_expr import LinearExpression N1 = 10 N2 = 100000 m = pyo.ConcreteModel() m.x = pyo.Var(list(range(N1))) timer = TicTocTimer() timer.tic() for i in range(N2): e = sum(i * m.x[i] for i in range(N1)) timer.toc('created expression with sum function') for i in range(N2): coefs = [i for i in range(N1)] lin_vars = [m.x[i] for i in range(N1)] e = LinearExpression(constant=0, linear_coefs=coefs, linear_vars=lin_vars) timer.toc('created expression with LinearExpression constructor')
def solve(self, model, **kwds): config = self.config(kwds, preserve_implicit=True) if not isinstance(model, Block): raise ValueError("PyomoCyIpoptSolver.solve(model): model " "must be a Pyomo Block") # If this is a Pyomo model / block, then we need to create # the appropriate PyomoNLP, then wrap it in a CyIpoptNLP grey_box_blocks = list(model.component_data_objects( egb.ExternalGreyBoxBlock, active=True)) if grey_box_blocks: # nlp = pyomo_nlp.PyomoGreyBoxNLP(model) nlp = pyomo_grey_box.PyomoNLPWithGreyBoxBlocks(model) else: nlp = pyomo_nlp.PyomoNLP(model) problem = CyIpoptNLP(nlp, intermediate_callback=config.intermediate_callback) xl = problem.x_lb() xu = problem.x_ub() gl = problem.g_lb() gu = problem.g_ub() nx = len(xl) ng = len(gl) cyipopt_solver = cyipopt.Problem( n=nx, m=ng, problem_obj=problem, lb=xl, ub=xu, cl=gl, cu=gu ) # check if we need scaling obj_scaling, x_scaling, g_scaling = problem.scaling_factors() if any(_ is not None for _ in (obj_scaling, x_scaling, g_scaling)): # need to set scaling factors if obj_scaling is None: obj_scaling = 1.0 if x_scaling is None: x_scaling = np.ones(nx) if g_scaling is None: g_scaling = np.ones(ng) try: set_scaling = cyipopt_solver.set_problem_scaling except AttributeError: # Fall back to pre-1.0.0 API set_scaling = cyipopt_solver.setProblemScaling set_scaling(obj_scaling, x_scaling, g_scaling) # add options try: add_option = cyipopt_solver.add_option except AttributeError: # Fall back to pre-1.0.0 API add_option = cyipopt_solver.addOption for k, v in config.options.items(): add_option(k, v) timer = TicTocTimer() try: # We preemptively set up the TeeStream, even if we aren't # going to use it: the implementation is such that the # context manager does nothing (i.e., doesn't start up any # processing threads) until afer a client accesses # STDOUT/STDERR with TeeStream(sys.stdout) as _teeStream: if config.tee: try: fd = sys.stdout.fileno() except (io.UnsupportedOperation, AttributeError): # If sys,stdout doesn't have a valid fileno, # then create one using the TeeStream fd = _teeStream.STDOUT.fileno() else: fd = None with redirect_fd(fd=1, output=fd, synchronize=False): x, info = cyipopt_solver.solve(problem.x_init()) solverStatus = SolverStatus.ok except: msg = "Exception encountered during cyipopt solve:" logger.error(msg, exc_info=sys.exc_info()) solverStatus = SolverStatus.unknown raise wall_time = timer.toc(None) results = SolverResults() if config.load_solutions: nlp.set_primals(x) nlp.set_duals(info['mult_g']) nlp.load_state_into_pyomo( bound_multipliers=(info['mult_x_L'], info['mult_x_U'])) else: soln = results.solution.add() soln.variable.update( (i, {'Value':j, 'ipopt_zL_out': zl, 'ipopt_zU_out': zu}) for i,j,zl,zu in zip( nlp.variable_names(), x, info['mult_x_L'], info['mult_x_U'] ) ) soln.constraint.update( (i, {'Dual':j}) for i,j in zip( nlp.constraint_names(), info['mult_g'])) results.problem.name = model.name obj = next(model.component_data_objects(Objective, active=True)) if obj.sense == minimize: results.problem.sense = ProblemSense.minimize results.problem.upper_bound = info['obj_val'] else: results.problem.sense = ProblemSense.maximize results.problem.lower_bound = info['obj_val'] results.problem.number_of_objectives = 1 results.problem.number_of_constraints = ng results.problem.number_of_variables = nx results.problem.number_of_binary_variables = 0 results.problem.number_of_integer_variables = 0 results.problem.number_of_continuous_variables = nx # TODO: results.problem.number_of_nonzeros results.solver.name = 'cyipopt' results.solver.return_code = info['status'] results.solver.message = info['status_msg'] results.solver.wallclock_time = wall_time status_enum = _cyipopt_status_enum[info['status_msg']] results.solver.termination_condition = _ipopt_term_cond[status_enum] results.solver.status = TerminationCondition.to_solver_status( results.solver.termination_condition) if config.return_nlp: return results, nlp return results
def test_TicTocTimer_tictoc(self): RES = 1e-2 # resolution (seconds) timer = TicTocTimer() abs_time = time.time() time.sleep(0.1) with capture_output() as out: start_time = time.time() timer.tic(None) self.assertEqual(out.getvalue(), '') with capture_output() as out: start_time = time.time() timer.tic() self.assertRegex( out.getvalue(), r'\[ [.0-9]+\] Resetting the tic/toc delta timer' ) time.sleep(0.1) with capture_output() as out: delta = timer.toc() self.assertAlmostEqual(time.time() - start_time, delta, delta=RES) self.assertAlmostEqual(0, timer.toc(None), delta=RES) self.assertRegex( out.getvalue(), r'\[\+ [.0-9]+\] .* in test_TicTocTimer_tictoc' ) with capture_output() as out: total = timer.toc(delta=False) self.assertAlmostEqual(time.time() - abs_time, total, delta=RES) self.assertRegex( out.getvalue(), r'\[ [.0-9]+\] .* in test_TicTocTimer_tictoc' ) ref = 0 ref -= time.time() time.sleep(0.1) timer.stop() ref += time.time() cumul_stop1 = timer.toc(None) with self.assertRaisesRegex( RuntimeError, 'Stopping a TicTocTimer that was already stopped'): timer.stop() time.sleep(0.1) cumul_stop2 = timer.toc(None) self.assertEqual(cumul_stop1, cumul_stop2) timer.start() ref -= time.time() time.sleep(0.1) # Note: pypy on GHA frequently has timing differences of >0.02s # for the following tests RES = 5e-2 with capture_output() as out: delta = timer.toc() timer.stop() ref += time.time() self.assertAlmostEqual(ref, delta, delta=RES) #self.assertAlmostEqual(0, timer.toc(None), delta=RES) self.assertRegex( out.getvalue(), r'\[ [.0-9]+\| 1\] .* in test_TicTocTimer_tictoc' ) with capture_output() as out: # Note that delta is ignored if the timer is a cumulative timer total = timer.toc(delta=False) self.assertAlmostEqual(delta, total, delta=RES) self.assertRegex( out.getvalue(), r'\[ [.0-9]+\| 1\] .* in test_TicTocTimer_tictoc' )
def solve(self, model, **kwds): config = self.config(kwds, preserve_implicit=True) if not isinstance(model, Block): raise ValueError("PyomoCyIpoptSolver.solve(model): model " "must be a Pyomo Block") # If this is a Pyomo model / block, then we need to create # the appropriate PyomoNLP, then wrap it in a CyIpoptNLP grey_box_blocks = list( model.component_data_objects(egb.ExternalGreyBoxBlock, active=True)) if grey_box_blocks: nlp = pyomo_nlp.PyomoGreyBoxNLP(model) else: nlp = pyomo_nlp.PyomoNLP(model) problem = CyIpoptNLP(nlp) xl = problem.x_lb() xu = problem.x_ub() gl = problem.g_lb() gu = problem.g_ub() nx = len(xl) ng = len(gl) cyipopt_solver = ipopt.problem(n=nx, m=ng, problem_obj=problem, lb=xl, ub=xu, cl=gl, cu=gu) # check if we need scaling obj_scaling, x_scaling, g_scaling = problem.scaling_factors() if any(_ is not None for _ in (obj_scaling, x_scaling, g_scaling)): # need to set scaling factors if obj_scaling is None: obj_scaling = 1.0 if x_scaling is None: x_scaling = np.ones(nx) if g_scaling is None: g_scaling = np.ones(ng) cyipopt_solver.setProblemScaling(obj_scaling, x_scaling, g_scaling) # add options for k, v in config.options.items(): cyipopt_solver.addOption(k, v) timer = TicTocTimer() try: if config.tee: x, info = cyipopt_solver.solve(problem.x_init()) else: newstdout = _redirect_stdout() x, info = cyipopt_solver.solve(problem.x_init()) os.dup2(newstdout, 1) solverStatus = SolverStatus.ok except: msg = "Exception encountered during cyipopt solve:" logger.error(msg, exc_info=sys.exc_info()) solverStatus = SolverStatus.unknown raise wall_time = timer.toc(None) results = SolverResults() if config.load_solutions: nlp.set_primals(x) nlp.set_duals(info['mult_g']) nlp.load_state_into_pyomo(bound_multipliers=(info['mult_x_L'], info['mult_x_U'])) else: soln = results.solution.add() soln.variable.update((i, { 'Value': j, 'ipopt_zL_out': zl, 'ipopt_zU_out': zu }) for i, j, zl, zu in zip(nlp.variable_names(), x, info['mult_x_L'], info['mult_x_U'])) soln.constraint.update((i, { 'Dual': j }) for i, j in zip(nlp.constraint_names(), info['mult_g'])) results.problem.name = model.name obj = next(model.component_data_objects(Objective, active=True)) if obj.sense == minimize: results.problem.sense = ProblemSense.minimize results.problem.upper_bound = info['obj_val'] else: results.problem.sense = ProblemSense.maximize results.problem.lower_bound = info['obj_val'] results.problem.number_of_objectives = 1 results.problem.number_of_constraints = ng results.problem.number_of_variables = nx results.problem.number_of_binary_variables = 0 results.problem.number_of_integer_variables = 0 results.problem.number_of_continuous_variables = nx # TODO: results.problem.number_of_nonzeros results.solver.name = 'cyipopt' results.solver.return_code = info['status'] results.solver.message = info['status_msg'] results.solver.wallclock_time = wall_time status_enum = _cyipopt_status_enum[info['status_msg']] results.solver.termination_condition = _ipopt_term_cond[status_enum] results.solver.status = TerminationCondition.to_solver_status( results.solver.termination_condition) return results
report_timing() print('Building model') print('--------------') m = create_warehouse_model(num_locations=200, num_customers=200) # @:report_timing # @report_timing_with_lin_expr: print('Building model with LinearExpression') print('------------------------------------') m = create_warehouse_linear_expr(num_locations=200, num_customers=200) # @:report_timing_with_lin_expr report_timing(False) # @tic_toc_timer: timer = TicTocTimer() timer.tic('start') m = create_warehouse_model(num_locations=200, num_customers=200) timer.toc('Built model') solve_warehouse_location(m) timer.toc('Wrote LP file and solved') # @:tic_toc_timer # @time_parametric: solve_parametric() timer.toc('Finished parameter sweep') # @:time_parametric # @profile_parametric: pr = cProfile.Profile() pr.enable()
def test_TicTocTimer_tictoc(self): SLEEP = 0.1 RES = 0.01 # resolution (seconds): 1/10 the sleep abs_time = time.time() timer = TicTocTimer() time.sleep(SLEEP) with capture_output() as out: start_time = time.time() timer.tic(None) self.assertEqual(out.getvalue(), '') with capture_output() as out: start_time = time.time() timer.tic() self.assertRegex( out.getvalue(), r'\[ [.0-9]+\] Resetting the tic/toc delta timer' ) time.sleep(SLEEP) ref = time.time() with capture_output() as out: delta = timer.toc() self.assertAlmostEqual(ref - start_time, delta, delta=RES) self.assertAlmostEqual(0, timer.toc(None), delta=RES) self.assertRegex( out.getvalue(), r'\[\+ [.0-9]+\] .* in test_TicTocTimer_tictoc' ) ref = time.time() with capture_output() as out: total = timer.toc(delta=False) self.assertAlmostEqual(ref - abs_time, total, delta=RES) self.assertRegex( out.getvalue(), r'\[ [.0-9]+\] .* in test_TicTocTimer_tictoc' ) ref *= -1 time.sleep(SLEEP) ref += time.time() timer.stop() cumul_stop1 = timer.toc(None) self.assertAlmostEqual(ref, cumul_stop1, delta=RES) with self.assertRaisesRegex( RuntimeError, 'Stopping a TicTocTimer that was already stopped'): timer.stop() time.sleep(SLEEP) cumul_stop2 = timer.toc(None) self.assertEqual(cumul_stop1, cumul_stop2) ref -= time.time() timer.start() time.sleep(SLEEP) # Note: pypy and osx (py3.8) on GHA occasionally have timing # differences of >0.01s for the following tests if 'pypy_version_info' in dir(sys) or sys.platform == 'darwin': RES *= 2 with capture_output() as out: ref += time.time() timer.stop() delta = timer.toc() self.assertAlmostEqual(ref, delta, delta=RES) #self.assertAlmostEqual(0, timer.toc(None), delta=RES) self.assertRegex( out.getvalue(), r'\[ [.0-9]+\| 1\] .* in test_TicTocTimer_tictoc' ) with capture_output() as out: # Note that delta is ignored if the timer is a cumulative timer total = timer.toc(delta=False) self.assertAlmostEqual(delta, total, delta=RES) self.assertRegex( out.getvalue(), r'\[ [.0-9]+\| 1\] .* in test_TicTocTimer_tictoc' )
def test_stochpdegas_automatic(self): timer = TicTocTimer() from .stochpdegas_automatic import model instance = model.create_instance( os.path.join(_dir, 'stochpdegas_automatic.dat')) self.recordData('create_instance', timer.toc('create_instance')) # discretize model discretizer = TransformationFactory('dae.finite_difference') discretizer.apply_to(instance, nfe=1, wrt=instance.DIS, scheme='FORWARD') discretizer.apply_to(instance, nfe=47, wrt=instance.TIME, scheme='BACKWARD') self.recordData('discretize', timer.toc('discretize')) # What it should be to match description in paper #discretizer.apply_to(instance,nfe=48,wrt=instance.TIME,scheme='BACKWARD') TimeStep = instance.TIME.at(2) - instance.TIME.at(1) def supcost_rule(m, k): return sum(m.cs * m.s[k, j, t] * (TimeStep) for j in m.SUP for t in m.TIME.get_finite_elements()) instance.supcost = Expression(instance.SCEN, rule=supcost_rule) def boostcost_rule(m, k): return sum(m.ce * m.pow[k, j, t] * (TimeStep) for j in m.LINK_A for t in m.TIME.get_finite_elements()) instance.boostcost = Expression(instance.SCEN, rule=boostcost_rule) def trackcost_rule(m, k): return sum(m.cd * (m.dem[k, j, t] - m.stochd[k, j, t])**2.0 for j in m.DEM for t in m.TIME.get_finite_elements()) instance.trackcost = Expression(instance.SCEN, rule=trackcost_rule) def sspcost_rule(m, k): return sum(m.cT * (m.px[k, i, m.TIME.last(), j] - m.px[k, i, m.TIME.first(), j])**2.0 for i in m.LINK for j in m.DIS) instance.sspcost = Expression(instance.SCEN, rule=sspcost_rule) def ssfcost_rule(m, k): return sum(m.cT * (m.fx[k, i, m.TIME.last(), j] - m.fx[k, i, m.TIME.first(), j])**2.0 for i in m.LINK for j in m.DIS) instance.ssfcost = Expression(instance.SCEN, rule=ssfcost_rule) def cost_rule(m, k): return 1e-6 * (m.supcost[k] + m.boostcost[k] + m.trackcost[k] + m.sspcost[k] + m.ssfcost[k]) instance.cost = Expression(instance.SCEN, rule=cost_rule) def mcost_rule(m): return (1.0 / m.S) * sum(m.cost[k] for k in m.SCEN) instance.mcost = Expression(rule=mcost_rule) def eqcvar_rule(m, k): return m.cost[k] - m.nu <= m.phi[k] instance.eqcvar = Constraint(instance.SCEN, rule=eqcvar_rule) def obj_rule(m): return (1.0 - m.cvar_lambda) * m.mcost + m.cvar_lambda * m.cvarcost instance.obj = Objective(rule=obj_rule) self.recordData('postprocessing', timer.toc('postprocessing')) for fmt in ('nl', 'bar', 'gams'): if not getattr(self, fmt, 0): continue writer = WriterFactory(fmt) fname = 'tmp.test.' + fmt self.assertFalse(os.path.exists(fname)) try: timer.tic(None) writer(instance, fname, lambda x: True, {}) _time = timer.toc(fmt) self.assertTrue(os.path.exists(fname)) self.recordData(fmt, _time) finally: try: os.remove(fname) except: pass
def test_TicTocTimer_tictoc(self): SLEEP = 0.1 RES = 0.02 # resolution (seconds): 1/5 the sleep # Note: pypy on GHA occasionally has timing # differences of >0.04s if 'pypy_version_info' in dir(sys): RES *= 2.5 # Note: previously, OSX on GHA also had significantly nosier tests # if sys.platform == 'darwin': # RES *= 2 abs_time = time.perf_counter() timer = TicTocTimer() time.sleep(SLEEP) with capture_output() as out: start_time = time.perf_counter() timer.tic(None) self.assertEqual(out.getvalue(), '') with capture_output() as out: start_time = time.perf_counter() timer.tic() self.assertRegex( out.getvalue(), r'\[ [.0-9]+\] Resetting the tic/toc delta timer' ) time.sleep(SLEEP) ref = time.perf_counter() with capture_output() as out: delta = timer.toc() self.assertAlmostEqual(ref - start_time, delta, delta=RES) self.assertAlmostEqual(0, timer.toc(None), delta=RES) self.assertRegex( out.getvalue(), r'\[\+ [.0-9]+\] .* in test_TicTocTimer_tictoc' ) ref = time.perf_counter() with capture_output() as out: total = timer.toc(delta=False) self.assertAlmostEqual(ref - abs_time, total, delta=RES) self.assertRegex( out.getvalue(), r'\[ [.0-9]+\] .* in test_TicTocTimer_tictoc' ) ref *= -1 time.sleep(SLEEP) ref += time.perf_counter() timer.stop() cumul_stop1 = timer.toc(None) self.assertAlmostEqual(ref, cumul_stop1, delta=RES) with self.assertRaisesRegex( RuntimeError, 'Stopping a TicTocTimer that was already stopped'): timer.stop() time.sleep(SLEEP) cumul_stop2 = timer.toc(None) self.assertEqual(cumul_stop1, cumul_stop2) ref -= time.perf_counter() timer.start() time.sleep(SLEEP) with capture_output() as out: ref += time.perf_counter() timer.stop() delta = timer.toc() self.assertAlmostEqual(ref, delta, delta=RES) #self.assertAlmostEqual(0, timer.toc(None), delta=RES) self.assertRegex( out.getvalue(), r'\[ [.0-9]+\| 1\] .* in test_TicTocTimer_tictoc' ) with capture_output() as out: # Note that delta is ignored if the timer is a cumulative timer total = timer.toc(delta=False) self.assertAlmostEqual(delta, total, delta=RES) self.assertRegex( out.getvalue(), r'\[ [.0-9]+\| 1\] .* in test_TicTocTimer_tictoc' )
def build_multiperiod_design(m, flowsheet, initialization=None, unfix_dof=None, flowsheet_options={}, initialization_options={}, unfix_dof_options={}, solver=None, verbose=True, stochastic=False, multiyear=False, multiple_days=False, **kwargs): """ This function constructs multiperiod optimization model """ # Create timer object timer = TicTocTimer() timer.tic("Processing input information.") if stochastic: # If True, set_scenarios must either be passed as an argument, # or it should defined as an attribute of the model if "set_scenarios" in kwargs: set_scenarios = kwargs["set_scenarios"] elif hasattr(m, "set_scenarios"): set_scenarios = m.set_scenarios else: raise Exception(f"stochastic option is set to True, but set_scenarios has " f"not been defined. Either pass set_scenarios as an argument " f"or define it as an attribute of the model.") if multiyear: # If True, set_years must either be passed as an argument, # or it should defined as an attribute of the model if "set_years" in kwargs: set_years = kwargs["set_years"] elif hasattr(m, "set_years"): set_years = m.set_years else: raise Exception(f"multiyear option is set to True, but set_years has " f"not been defined. Either pass set_years as an argument " f"or define it as an attribute of the model.") if multiple_days: # If True, set_days must either be passed as an argument, # or it should defined as an attribute of the model if "set_days" in kwargs: set_days = kwargs["set_days"] elif hasattr(m, "set_days"): set_days = m.set_days else: raise Exception(f"multiple_days option is set to True, but set_days has " f"not been defined. Either pass set_days as an argument " f"or define it as an attribute of the model.") # Set of time periods if "set_time" in kwargs: set_time = kwargs["set_time"] elif hasattr(m, "set_time"): set_time = m.set_time else: raise Exception(f"set_time is a required option. Either pass set_time as " f"an argument or define it as an attribute of the model.") # Set solver object if solver is None: solver = get_solver() # Construct the set of time periods if multiyear and multiple_days: set_period = [(t, d, y) for y in set_years for d in set_days for t in set_time] elif multiple_days: set_period = [(t, d) for d in set_days for t in set_time] else: set_period = [t for t in set_time] """ Period rule """ timer.toc("Beginning the formulation of the multiperiod problem.") def _period_model_rule(options, verbose_flag): def _period_model(blk): if verbose_flag: print("Constructing flowsheet model for ", blk.name) flowsheet(blk, options=options) return _period_model def _build_scenario_model(blk): blk.period = Block(set_period, rule=_period_model_rule(flowsheet_options, verbose)) return blk # Construct the multiperiod model if stochastic: m.scenario = Block(set_scenarios, rule=_build_scenario_model) else: _build_scenario_model(m) timer.toc("Completed the formulation of the multiperiod problem") """ Initialization routine """ if initialization is None: print("*** WARNING *** Initialization function is not provided. " "Returning the multiperiod model without initialization.") return b = ConcreteModel() flowsheet(b, options=flowsheet_options) initialization(b, options=initialization_options) result = solver.solve(b) try: assert check_optimal_termination(result) except AssertionError: print(f"Flowsheet did not converge to optimality " f"after fixing the degrees of freedom.") raise # Save the solution in json file to_json(b, fname="temp_initialized_model.json") timer.toc("Created an instance of the flowsheet and initialized it.") # Initialize the multiperiod optimization model if stochastic: for s in set_scenarios: for p in set_period: from_json(m.scenario[s].period[p], fname="temp_initialized_model.json") else: for p in set_period: from_json(m.period[p], fname="temp_initialized_model.json") timer.toc("Initialized the entire multiperiod optimization model.") """ Unfix the degrees of freedom in each period model for optimization model """ if unfix_dof is None: print("*** WARNING *** unfix_dof function is not provided. " "Returning the model without unfixing degrees of freedom") return if stochastic: for s in set_scenarios: for p in set_period: unfix_dof(m.scenario[s].period[p], options=unfix_dof_options) else: for p in set_period: unfix_dof(m.period[p], options=unfix_dof_options) timer.toc("Unfixed the degrees of freedom from each period model.")
def __init__(self, data): super(DataRecorder, self).__init__() self._data = data self._timingHandler = None self._timer = TicTocTimer() self._category = {}