cvxpy / cvxpy

A Python-embedded modeling language for convex optimization problems.
https://www.cvxpy.org
Apache License 2.0
5.37k stars 1.05k forks source link

cvxpy crash if mosek doesn't reach a solution / is innacurate #1226

Closed samuelstjean closed 3 years ago

samuelstjean commented 3 years ago

Describe the bug Seems like it is missing handling this case when giving the output, works fine with scs and it displays that it was inaccurate.

To Reproduce See the link, not exactly minimal since it's very problem specific, but just run as is https://pastebin.com/YggE731p

Expected behavior cvxpy should report that the solution is inaccurate or that something failed internally, not crash

Output For scs I get

print(time() - tt, prob.status, prob.value)
19.485684871673584 optimal_inaccurate 332.06892127404893

For mosek I get

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-86-098e2a26abc0> in <module>
      5 mosek_params = (mosek.iparam.intpnt_solve_form, mosek.solveform.dual)
      6 tt = time()
----> 7 prob.solve(solver=solver, verbose=verbose)
      8 print(time() - tt, prob.status, prob.value)
      9 X = X.value

~/anaconda3/envs/py37/lib/python3.7/site-packages/cvxpy/problems/problem.py in solve(self, *args, **kwargs)
    394         else:
    395             solve_func = Problem._solve
--> 396         return solve_func(self, *args, **kwargs)
    397 
    398     @classmethod

~/anaconda3/envs/py37/lib/python3.7/site-packages/cvxpy/problems/problem.py in _solve(self, solver, warm_start, verbose, gp, qcp, requires_grad, enforce_dpp, **kwargs)
    752         solution = solving_chain.solve_via_data(
    753             self, data, warm_start, verbose, kwargs)
--> 754         self.unpack_results(solution, solving_chain, inverse_data)
    755         return self.value
    756 

~/anaconda3/envs/py37/lib/python3.7/site-packages/cvxpy/problems/problem.py in unpack_results(self, solution, chain, inverse_data)
   1068                     "Try another solver, or solve with verbose=True for more "
   1069                     "information.")
-> 1070         self.unpack(solution)
   1071         self._solver_stats = SolverStats(self._solution.attr,
   1072                                          chain.solver.name())

~/anaconda3/envs/py37/lib/python3.7/site-packages/cvxpy/problems/problem.py in unpack(self, solution)
   1028                     dv.save_value(None)
   1029         else:
-> 1030             raise ValueError("Cannot unpack invalid solution: %s" % solution)
   1031 
   1032         self._value = solution.opt_val

ValueError: Cannot unpack invalid solution: Solution(status=UNKNOWN, opt_val=nan, primal_vars={}, dual_vars={}, attr={'solve_time': 1.4013481140136719})

Version

Additional context Seems like it's just missing handling this case as scs doesn't crash, but reports an inaccurate solution.

rileyjmurray commented 3 years ago

I ran your test case on the master branch, which is slightly ahead of 1.1.7, but not in a way that should affect this problem. On running with verbose=True, I get this output from MOSEK (I've removed some intermediate log lines about dual infeasibility):

Problem
  Name                   :                 
  Objective sense        : max             
  Type                   : CONIC (conic optimization problem)
  Constraints            : 1577            
  Cones                  : 1               
  Scalar variables       : 4103            
  Matrix variables       : 2               
  Integer variables      : 0               
Optimizer started.
Problem
  Name                   :                 
  Objective sense        : max             
  Type                   : CONIC (conic optimization problem)
  Constraints            : 1577            
  Cones                  : 1               
  Scalar variables       : 4103            
  Matrix variables       : 2               
  Integer variables      : 0               
Optimizer  - threads                : 4               
Optimizer  - solved problem         : the primal      
Optimizer  - Constraints            : 1576
Optimizer  - Cones                  : 2
Optimizer  - Scalar variables       : 3778              conic                  : 1227            
Optimizer  - Semi-definite variables: 2                 scalarized             : 650             
Factor     - setup time             : 0.05              dense det. time        : 0.00            
Factor     - ML order time          : 0.02              GP order time          : 0.00            
Factor     - nonzeros before factor : 4.63e+05          after factor           : 4.72e+05        
Factor     - dense dim.             : 4                 flops                  : 3.12e+08        
ITE PFEAS    DFEAS    GFEAS    PRSTATUS   POBJ              DOBJ              MU       TIME  
0   2.0e+01  8.0e+01  1.5e+00  0.00e+00   -5.000000000e-01  0.000000000e+00   1.0e+00  0.06  
1   1.5e+01  6.1e+01  1.3e+00  -9.39e-01  1.366991388e+01   1.388187525e+01   7.7e-01  0.09  
2   9.0e+00  3.6e+01  9.6e-01  -9.19e-01  4.412089705e+01   4.354050656e+01   4.5e-01  0.11  
3   1.2e+00  4.8e+00  2.4e-01  -8.53e-01  3.264961066e+02   3.199782719e+02   6.0e-02  0.14  
4   5.3e-01  2.1e+00  8.5e-02  7.97e-02   3.593670989e+02   3.553213835e+02   2.7e-02  0.17  
5   2.9e-01  1.2e+00  3.8e-02  4.34e-01   3.625593558e+02   3.598403583e+02   1.5e-02  0.20  
6   1.0e-01  4.2e-01  8.4e-03  6.85e-01   3.510756710e+02   3.500416782e+02   5.2e-03  0.22  
7   1.7e-02  6.9e-02  4.1e-04  9.76e-01   3.325964715e+02   3.325117310e+02   8.6e-04  0.26  
8   3.1e-03  1.3e-02  3.7e-05  1.38e+00   3.328344797e+02   3.328129947e+02   1.6e-04  0.29  
9   3.0e-03  1.2e-02  3.3e-05  1.17e+00   3.327343577e+02   3.327142160e+02   1.5e-04  0.31  
10  1.5e-03  5.9e-03  1.2e-05  1.14e+00   3.324741075e+02   3.324638645e+02   7.4e-05  0.34  
11  1.1e-03  4.6e-03  1.1e-05  5.43e-01   3.326626767e+02   3.326475602e+02   5.7e-05  0.37  
12  1.1e-03  4.3e-03  1.0e-05  1.03e-01   3.325632319e+02   3.325491128e+02   5.4e-05  0.39  
13  8.8e-04  3.5e-03  8.8e-06  1.19e-01   3.327319354e+02   3.327153559e+02   4.4e-05  0.42  
14  4.7e-04  1.9e-03  2.8e-06  6.37e-01   3.323034772e+02   3.322980604e+02   2.4e-05  0.44  
15  7.9e-05  3.2e-04  6.3e-07  5.13e-01   3.326266869e+02   3.326157160e+02   4.0e-06  0.48  
16  8.6e-06  3.4e-05  2.1e-07  -7.23e-01  3.373430847e+02   3.372348659e+02   4.3e-07  0.50  
17  7.7e-07  3.1e-06  5.8e-08  -9.66e-01  3.848943372e+02   3.838840702e+02   3.8e-08  0.52  
18  2.5e-07  1.0e-06  3.3e-08  -9.98e-01  4.897373768e+02   4.866242156e+02   1.2e-08  0.55  
19  1.5e-07  5.8e-07  2.5e-08  -9.99e-01  6.152183176e+02   6.099485607e+02   7.3e-09  0.59  
20  4.7e-08  1.9e-07  1.4e-08  -1.00e+00  1.162610766e+03   1.146780775e+03   2.4e-09  0.62  
21  1.1e-08  4.6e-08  7.0e-09  -1.00e+00  3.780338471e+03   3.714824931e+03   5.7e-10  0.65  
22  6.2e-09  2.5e-08  5.1e-09  -1.00e+00  6.507896838e+03   6.387875826e+03   3.1e-10  0.69  
23  4.9e-10  2.0e-09  1.7e-09  -1.00e+00  7.842812556e+04   7.697414332e+04   2.5e-11  0.73  
24  3.2e-13  1.3e-12  3.0e-08  -1.00e+00  1.217074583e+08   1.194440790e+08   1.6e-14  0.76  
25  2.8e-14  1.3e-16  1.4e-06  -1.00e+00  1.217069690e+12   1.194435961e+12   1.6e-18  0.80  
26  2.8e-14  1.3e-16  1.4e-06  -1.00e+00  1.217069690e+12   1.194435961e+12   1.6e-18  0.84  
27  2.3e-14  6.3e-17  1.6e-06  -1.00e+00  2.433895989e+12   2.388633057e+12   7.9e-19  0.87  
28  1.4e-14  3.2e-17  6.2e-07  -1.00e+00  4.867305236e+12   4.776788429e+12   4.0e-19  0.91  
29  1.4e-14  3.2e-17  6.2e-07  -1.00e+00  4.867305236e+12   4.776788429e+12   4.0e-19  0.95  
30  1.4e-14  3.2e-17  6.2e-07  -1.00e+00  4.867305236e+12   4.776788429e+12   4.0e-19  0.99  
Optimizer terminated. Time: 1.03    

Interior-point solution summary
  Problem status  : DUAL_INFEASIBLE
  Solution status : DUAL_INFEASIBLE_CER
  Primal.  obj: 1.0116970006e-02    nrm: 7e+01    Viol.  con: 4e-13    var: 0e+00    barvar: 0e+00    cones: 0e+00  

which gives prob.value == np.inf (the minimization problem was infeasible). This is with MOSEK 9.2.18. I also with with a dualize option that's mentioned in the error you posted, but then I get this warning from MOSEK

MOSEK warning 950: No automatic dualizer is available for the specified problem.

Please post the result of solving the problem with MOSEK and setting verbose=True.

samuelstjean commented 3 years ago

It's totally possible it doesn't work (I was adding some more constraints to something that was workking, although here SCS returns an inaccurate solution according to itself), I was mostly surprised that the case of unknown answer does not seem to be accounted for somewhere in the return path to cvxpy. This is what verbose=True gives me

Problem
  Name                   :                 
  Objective sense        : max             
  Type                   : CONIC (conic optimization problem)
  Constraints            : 1577            
  Cones                  : 1               
  Scalar variables       : 4103            
  Matrix variables       : 2               
  Integer variables      : 0               

Optimizer started.
Problem
  Name                   :                 
  Objective sense        : max             
  Type                   : CONIC (conic optimization problem)
  Constraints            : 1577            
  Cones                  : 1               
  Scalar variables       : 4103            
  Matrix variables       : 2               
  Integer variables      : 0               

Optimizer  - threads                : 4               
Optimizer  - solved problem         : the primal      
Optimizer  - Constraints            : 1576
Optimizer  - Cones                  : 2
Optimizer  - Scalar variables       : 3778              conic                  : 1227            
Optimizer  - Semi-definite variables: 2                 scalarized             : 650             
Factor     - setup time             : 0.13              dense det. time        : 0.00            
Factor     - ML order time          : 0.07              GP order time          : 0.00            
Factor     - nonzeros before factor : 4.63e+05          after factor           : 4.72e+05        
Factor     - dense dim.             : 4                 flops                  : 3.12e+08        
ITE PFEAS    DFEAS    GFEAS    PRSTATUS   POBJ              DOBJ              MU       TIME  
0   2.0e+01  8.0e+01  1.5e+00  0.00e+00   -5.000000000e-01  0.000000000e+00   1.0e+00  0.27  
1   1.5e+01  6.1e+01  1.3e+00  -9.39e-01  1.366991388e+01   1.388187525e+01   7.7e-01  0.39  
2   9.0e+00  3.6e+01  9.6e-01  -9.19e-01  4.412089705e+01   4.354050656e+01   4.5e-01  0.46  
3   1.2e+00  4.8e+00  2.4e-01  -8.53e-01  3.264961065e+02   3.199782719e+02   6.0e-02  0.51  
4   5.3e-01  2.1e+00  8.5e-02  7.97e-02   3.593670989e+02   3.553213835e+02   2.7e-02  0.56  
5   2.9e-01  1.2e+00  3.8e-02  4.34e-01   3.625593558e+02   3.598403583e+02   1.5e-02  0.59  
6   1.0e-01  4.2e-01  8.4e-03  6.85e-01   3.510756710e+02   3.500416782e+02   5.2e-03  0.63  
7   1.7e-02  6.9e-02  4.1e-04  9.76e-01   3.325964715e+02   3.325117310e+02   8.6e-04  0.67  
8   3.1e-03  1.3e-02  3.7e-05  1.38e+00   3.328344797e+02   3.328129947e+02   1.6e-04  0.72  
9   3.0e-03  1.2e-02  3.3e-05  1.17e+00   3.327343577e+02   3.327142160e+02   1.5e-04  0.76  
10  1.5e-03  5.9e-03  1.2e-05  1.14e+00   3.324741075e+02   3.324638645e+02   7.4e-05  0.80  
11  1.1e-03  4.6e-03  1.1e-05  5.43e-01   3.326626765e+02   3.326475600e+02   5.7e-05  0.84  
12  1.1e-03  4.3e-03  1.0e-05  1.03e-01   3.325632317e+02   3.325491126e+02   5.4e-05  0.88  
13  8.8e-04  3.5e-03  8.8e-06  1.19e-01   3.327319352e+02   3.327153557e+02   4.4e-05  0.92  
14  4.7e-04  1.9e-03  2.8e-06  6.37e-01   3.323034770e+02   3.322980602e+02   2.4e-05  0.96  
15  7.9e-05  3.2e-04  6.3e-07  5.13e-01   3.326266829e+02   3.326157121e+02   4.0e-06  1.01  
16  8.6e-06  3.4e-05  2.1e-07  -7.23e-01  3.373430769e+02   3.372348583e+02   4.3e-07  1.05  
17  7.7e-07  3.1e-06  5.8e-08  -9.66e-01  3.848946666e+02   3.838843940e+02   3.8e-08  1.09  
18  2.5e-07  1.0e-06  3.3e-08  -9.98e-01  4.897386322e+02   4.866254452e+02   1.2e-08  1.13  
19  1.5e-07  5.8e-07  2.5e-08  -9.99e-01  6.152245731e+02   6.099547008e+02   7.3e-09  1.18  
20  9.5e-08  1.9e-07  1.4e-08  -1.00e+00  1.162647043e+03   1.146816376e+03   2.4e-09  1.21  
21  2.3e-08  4.6e-08  6.9e-09  -1.00e+00  3.780375698e+03   3.714861431e+03   5.7e-10  1.26  
22  1.2e-08  2.5e-08  5.1e-09  -1.00e+00  6.508260425e+03   6.388232688e+03   3.1e-10  1.32  
23  9.9e-10  2.0e-09  1.3e-09  -1.00e+00  7.844694023e+04   7.699260910e+04   2.5e-11  1.36  
24  6.5e-13  1.3e-12  4.7e-09  -1.00e+00  1.218128836e+08   1.195475452e+08   1.6e-14  1.41  
25  6.3e-13  1.2e-12  2.3e-09  -1.00e+00  1.237462230e+08   1.214449306e+08   1.6e-14  1.47  
26  4.7e-13  9.3e-13  5.5e-11  -1.00e+00  1.649949229e+08   1.619265330e+08   1.2e-14  1.52  
27  4.7e-13  9.3e-13  5.5e-11  -1.00e+00  1.649949229e+08   1.619265330e+08   1.2e-14  1.57  
28  4.7e-13  9.3e-13  5.5e-11  -1.00e+00  1.649949229e+08   1.619265330e+08   1.2e-14  1.63  
Optimizer terminated. Time: 1.69    

Interior-point solution summary
  Problem status  : UNKNOWN
  Solution status : UNKNOWN
  Primal.  obj: 1.6499492288e+08    nrm: 1e+12    Viol.  con: 2e-01    var: 0e+00    barvar: 0e+00    cones: 0e+00  
  Dual.    obj: 1.6192653298e+08    nrm: 2e+07    Viol.  con: 0e+00    var: 2e-04    barvar: 2e-04    cones: 0e+00  
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-1-ae6a5ba76ce7> in <module>
    146 # solver = 'SCS'
    147 verbose = True
--> 148 prob.solve(solver=solver, verbose=verbose)

~/anaconda3/envs/py37/lib/python3.7/site-packages/cvxpy/problems/problem.py in solve(self, *args, **kwargs)
    394         else:
    395             solve_func = Problem._solve
--> 396         return solve_func(self, *args, **kwargs)
    397 
    398     @classmethod

~/anaconda3/envs/py37/lib/python3.7/site-packages/cvxpy/problems/problem.py in _solve(self, solver, warm_start, verbose, gp, qcp, requires_grad, enforce_dpp, **kwargs)
    752         solution = solving_chain.solve_via_data(
    753             self, data, warm_start, verbose, kwargs)
--> 754         self.unpack_results(solution, solving_chain, inverse_data)
    755         return self.value
    756 

~/anaconda3/envs/py37/lib/python3.7/site-packages/cvxpy/problems/problem.py in unpack_results(self, solution, chain, inverse_data)
   1068                     "Try another solver, or solve with verbose=True for more "
   1069                     "information.")
-> 1070         self.unpack(solution)
   1071         self._solver_stats = SolverStats(self._solution.attr,
   1072                                          chain.solver.name())

~/anaconda3/envs/py37/lib/python3.7/site-packages/cvxpy/problems/problem.py in unpack(self, solution)
   1028                     dv.save_value(None)
   1029         else:
-> 1030             raise ValueError("Cannot unpack invalid solution: %s" % solution)
   1031 
   1032         self._value = solution.opt_val

ValueError: Cannot unpack invalid solution: Solution(status=UNKNOWN, opt_val=nan, primal_vars={}, dual_vars={}, attr={'solve_time': 1.6907880306243896})
rileyjmurray commented 3 years ago

The "unknown" solver status should be handled. There is a chance that this is a regression from a rewrite of the MOSEK interface, first released in 1.1.6. We can look into this, but it would help if you could supply a problem that triggered the "unknown" status code for MOSEK.

aszekMosek commented 3 years ago

@rileyjmurray It reproduces for me on @samuelstjean's original problem, as well as when I set say MSK_IPAR_INTPNT_MAX_ITERATIONS to 1. Does the latter let you trigger it?

rileyjmurray commented 3 years ago

@aszekMosek I was able to reproduce the error when setting MSK_IPAR_INTPNT_MAX_ITERATIONS to 1. There was indeed a bug introduced in the MOSEK interface rewrite. The behavior isn't all that different now. Where before a ValueError was raised (with a useless message), now a SolverError is raised (with the same message that would appear in older cvxpy releases). Thanks for reporting this issue @samuelstjean.

samuelstjean commented 3 years ago

No prob, I guess an example to trigger the unknown error code as requested is not needed anymore? Seems like you already fixed it meanwhile, thanks.