19
19
from pyomo .core .base .param import _ParamData
20
20
from pyomo .core .base .block import _BlockData
21
21
from pyomo .core .base .objective import _GeneralObjectiveData
22
- from pyomo .common .config import document_kwargs_from_configdict
22
+ from pyomo .common .config import document_kwargs_from_configdict , ConfigValue
23
23
from pyomo .common .errors import ApplicationError
24
24
from pyomo .common .deprecation import deprecation_warning
25
+ from pyomo .common .modeling import NOTSET
25
26
from pyomo .opt .results .results_ import SolverResults as LegacySolverResults
26
27
from pyomo .opt .results .solution import Solution as LegacySolution
27
28
from pyomo .core .kernel .objective import minimize
@@ -347,6 +348,11 @@ class LegacySolverWrapper:
347
348
interface. Necessary for backwards compatibility.
348
349
"""
349
350
351
+ def __init__ (self , solver_io = None , ** kwargs ):
352
+ if solver_io is not None :
353
+ raise NotImplementedError ('Still working on this' )
354
+ super ().__init__ (** kwargs )
355
+
350
356
#
351
357
# Support "with" statements
352
358
#
@@ -358,51 +364,61 @@ def __exit__(self, t, v, traceback):
358
364
359
365
def _map_config (
360
366
self ,
361
- tee ,
362
- load_solutions ,
363
- symbolic_solver_labels ,
364
- timelimit ,
365
- # Report timing is no longer a valid option. We now always return a
366
- # timer object that can be inspected.
367
- report_timing ,
368
- raise_exception_on_nonoptimal_result ,
369
- solver_io ,
370
- suffixes ,
371
- logfile ,
372
- keepfiles ,
373
- solnfile ,
374
- options ,
367
+ tee = NOTSET ,
368
+ load_solutions = NOTSET ,
369
+ symbolic_solver_labels = NOTSET ,
370
+ timelimit = NOTSET ,
371
+ report_timing = NOTSET ,
372
+ raise_exception_on_nonoptimal_result = NOTSET ,
373
+ solver_io = NOTSET ,
374
+ suffixes = NOTSET ,
375
+ logfile = NOTSET ,
376
+ keepfiles = NOTSET ,
377
+ solnfile = NOTSET ,
378
+ options = NOTSET ,
375
379
):
376
380
"""Map between legacy and new interface configuration options"""
377
381
self .config = self .config ()
378
- self .config .tee = tee
379
- self .config .load_solutions = load_solutions
380
- self .config .symbolic_solver_labels = symbolic_solver_labels
381
- self .config .time_limit = timelimit
382
- self .config .solver_options .set_value (options )
382
+ if 'report_timing' not in self .config :
383
+ self .config .declare (
384
+ 'report_timing' , ConfigValue (domain = bool , default = False )
385
+ )
386
+ if tee is not NOTSET :
387
+ self .config .tee = tee
388
+ if load_solutions is not NOTSET :
389
+ self .config .load_solutions = load_solutions
390
+ if symbolic_solver_labels is not NOTSET :
391
+ self .config .symbolic_solver_labels = symbolic_solver_labels
392
+ if timelimit is not NOTSET :
393
+ self .config .time_limit = timelimit
394
+ if report_timing is not NOTSET :
395
+ self .config .report_timing = report_timing
396
+ if options is not NOTSET :
397
+ self .config .solver_options .set_value (options )
383
398
# This is a new flag in the interface. To preserve backwards compatibility,
384
399
# its default is set to "False"
385
- self .config .raise_exception_on_nonoptimal_result = (
386
- raise_exception_on_nonoptimal_result
387
- )
388
- if solver_io is not None :
400
+ if raise_exception_on_nonoptimal_result is not NOTSET :
401
+ self .config .raise_exception_on_nonoptimal_result = (
402
+ raise_exception_on_nonoptimal_result
403
+ )
404
+ if solver_io is not NOTSET and solver_io is not None :
389
405
raise NotImplementedError ('Still working on this' )
390
- if suffixes is not None :
406
+ if suffixes is not NOTSET and suffixes is not None :
391
407
raise NotImplementedError ('Still working on this' )
392
- if logfile is not None :
408
+ if logfile is not NOTSET and logfile is not None :
393
409
raise NotImplementedError ('Still working on this' )
394
410
if keepfiles or 'keepfiles' in self .config :
395
411
cwd = os .getcwd ()
396
412
deprecation_warning (
397
413
"`keepfiles` has been deprecated in the new solver interface. "
398
- "Use `working_dir` instead to designate a directory in which "
399
- f"files should be generated and saved. Setting `working_dir` to `{ cwd } `." ,
414
+ "Use `working_dir` instead to designate a directory in which files "
415
+ f"should be generated and saved. Setting `working_dir` to `{ cwd } `." ,
400
416
version = '6.7.1' ,
401
417
)
402
418
self .config .working_dir = cwd
403
419
# I believe this currently does nothing; however, it is unclear what
404
420
# our desired behavior is for this.
405
- if solnfile is not None :
421
+ if solnfile is not NOTSET :
406
422
if 'filename' in self .config :
407
423
filename = os .path .splitext (solnfile )[0 ]
408
424
self .config .filename = filename
@@ -504,28 +520,34 @@ def solve(
504
520
505
521
"""
506
522
original_config = self .config
507
- self ._map_config (
508
- tee ,
509
- load_solutions ,
510
- symbolic_solver_labels ,
511
- timelimit ,
512
- report_timing ,
513
- raise_exception_on_nonoptimal_result ,
514
- solver_io ,
515
- suffixes ,
516
- logfile ,
517
- keepfiles ,
518
- solnfile ,
519
- options ,
523
+
524
+ map_args = (
525
+ 'tee' ,
526
+ 'load_solutions' ,
527
+ 'symbolic_solver_labels' ,
528
+ 'timelimit' ,
529
+ 'report_timing' ,
530
+ 'raise_exception_on_nonoptimal_result' ,
531
+ 'solver_io' ,
532
+ 'suffixes' ,
533
+ 'logfile' ,
534
+ 'keepfiles' ,
535
+ 'solnfile' ,
536
+ 'options' ,
520
537
)
538
+ loc = locals ()
539
+ filtered_args = {k : loc [k ] for k in map_args if loc .get (k , None ) is not None }
540
+ self ._map_config (** filtered_args )
521
541
522
542
results : Results = super ().solve (model )
523
543
legacy_results , legacy_soln = self ._map_results (model , results )
524
-
525
544
legacy_results = self ._solution_handler (
526
545
load_solutions , model , results , legacy_results , legacy_soln
527
546
)
528
547
548
+ if self .config .report_timing :
549
+ print (results .timing_info .timer )
550
+
529
551
self .config = original_config
530
552
531
553
return legacy_results
@@ -555,3 +577,13 @@ def license_is_valid(self) -> bool:
555
577
556
578
"""
557
579
return bool (self .available ())
580
+
581
+ def config_block (self , init = False ):
582
+ from pyomo .scripting .solve_config import default_config_block
583
+
584
+ return default_config_block (self , init )[0 ]
585
+
586
+ def set_options (self , options ):
587
+ opts = {k : v for k , v in options .value ().items () if v is not None }
588
+ if opts :
589
+ self ._map_config (** opts )
0 commit comments