Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Check SCS performance on DUALC1 #19

Closed
stephane-caron opened this issue Nov 10, 2022 · 10 comments
Closed

Check SCS performance on DUALC1 #19

stephane-caron opened this issue Nov 10, 2022 · 10 comments
Assignees

Comments

@stephane-caron
Copy link
Member

From bodono/scs-python#63 (comment):

Looking at the instances you posted, I see for instance the first entry is DUALC1, which you have:
problem solver settings runtime found cost_error primal_error
DUALC1 scs default 1.48001 True 8.41269e+23 2.79628e+11

but in the results spreadsheet I have:
name solver status run_time iter obj_val obj_opt n m N setup_time solve_time scale scale_updates
DUALC1 SCS-3.0 optimal 0.002122163772583008 150 6154.912037803983 6155.2508 9 224 2025 0.330263 1.190224 0.04653712266416252 1

And I notice that the true objective value is listed as 6155.2508. My run of SCS finishes in 150 iterations and is close to the optimum with 6154.912037803983, but somehow your run has a cost_error of 8.41269e+23, which seems very high!

(FYI: in my csv the run_time is seconds as determined by a separate python timer, ie, it doesn't rely on the solvers own timers, and setup_time solve_time are both in milliseconds and are from the solvers own timer.)

@bodono
Copy link

bodono commented Nov 11, 2022

Here's a fresh run of DUALC1 with my code using the same settings as you I believe (1e-4 for both eps_abs and eps_rel, all other settings just the defaults):

 - Solving DUALC1 with solver SCS-3.0
 - Optimal objective 6155.2508
------------------------------------------------------------------
               SCS v3.2.1 - Splitting Conic Solver
        (c) Brendan O'Donoghue, Stanford University, 2012
------------------------------------------------------------------
problem:  variables n: 9, constraints m: 225
cones:    z: primal zero / dual free vars: 1
          b: box cone vars: 224
settings: eps_abs: 1.0e-04, eps_rel: 1.0e-04, eps_infeas: 1.0e-18
          alpha: 1.50, scale: 1.00e-01, adaptive_scale: 1
          max_iters: 100000, normalize: 1, rho_x: 1.00e-06
          acceleration_lookback: 10, acceleration_interval: 10
lin-sys:  sparse-direct-amd-qdldl
          nnz(A): 1944, nnz(P): 45
------------------------------------------------------------------
 iter | pri res | dua res |   gap   |   obj   |  scale  | time (s)
------------------------------------------------------------------
     0| 1.07e+03  3.16e+06  6.01e+05 -6.42e+06  1.00e-01  3.62e-04
   175| 8.89e-07  1.46e-02  3.31e-01  6.16e+03  1.00e-01  1.46e-03
------------------------------------------------------------------
status:  solved
timings: total: 1.46e-03s = setup: 2.92e-04s + solve: 1.17e-03s
         lin-sys: 7.43e-04s, cones: 1.89e-04s, accel: 4.06e-05s
------------------------------------------------------------------
objective = 6155.077695
------------------------------------------------------------------

I haven't tried the others from that list, but they are likely to be similar.

@bodono
Copy link

bodono commented Nov 11, 2022

When I run it from your code (the accuracies are 1e-7 here, but that should be ok):

│[2022-11-02 15:26:29,547] [info] Solving DUALC1 by scs with high_accuracy settings... (test_set.py:148)
│------------------------------------------------------------------
│               SCS v3.2.1 - Splitting Conic Solver
│        (c) Brendan O'Donoghue, Stanford University, 2012
│------------------------------------------------------------------
│problem:  variables n: 9, constraints m: 439
│cones:    z: primal zero / dual free vars: 1
│          l: linear vars: 428
│          b: box cone vars: 10
│settings: eps_abs: 1.0e-07, eps_rel: 1.0e-07, eps_infeas: 1.0e-07
│          alpha: 1.50, scale: 1.00e-01, adaptive_scale: 1
│          max_iters: 100000, normalize: 1, rho_x: 1.00e-06
│          acceleration_lookback: 10, acceleration_interval: 10
│          time_limit_secs: 1.00e+03
│lin-sys:  sparse-direct-amd-qdldl
│          nnz(A): 3870, nnz(P): 45
│------------------------------------------------------------------
│ iter | pri res | dua res |   gap   |   obj   |  scale  | time (s)
│------------------------------------------------------------------
│     0| 1.24e+20  1.53e+23  5.63e+40 -2.45e+38  1.00e-01  6.62e-04
│   250| 1.53e+12  6.65e+08  1.90e+22 -9.51e+21  6.86e-04  3.61e-03
│   500| 1.29e+12  8.85e+08  1.97e+22 -9.84e+21  6.86e-04  6.26e-03
│   750| 2.98e+11  3.55e+08  3.18e+21 -1.59e+21  5.18e-05  8.99e-03
│  1000| 2.98e+11  9.39e+09  3.64e+21 -1.82e+21  1.00e-06  1.17e-02
│  1250| 2.96e+11  6.27e+10  3.64e+21 -1.82e+21  1.00e-06  1.44e-02
│  1500| 2.95e+11  7.28e+10  3.64e+21 -1.82e+21  1.00e-06  1.71e-02
│  1750| 2.98e+11  3.19e+10  3.64e+21 -1.82e+21  1.00e-06  1.97e-02
│  2000| 3.00e+11  7.29e+10  3.64e+21 -1.82e+21  1.00e-06  2.24e-02
│  2250| 2.99e+11  4.53e+10  3.64e+21 -1.82e+21  1.00e-06  2.51e-02
│  2500| 2.97e+11  1.15e+10  3.63e+21 -1.82e+21  1.00e-06  2.78e-02
│  2750| 2.97e+11  9.13e+09  3.64e+21 -1.82e+21  1.00e-06  3.05e-02
│  3000| 2.95e+11  6.26e+10  3.65e+21 -1.83e+21  1.00e-06  3.31e-02
│  3250| 2.98e+11  3.46e+10  3.71e+21 -1.86e+21  1.00e-06  3.58e-02
│  3500| 2.98e+11  2.69e+10  3.63e+21 -1.82e+21  1.00e-06  3.84e-02

That's quite strange behaviour, and I would guess somehow the problem is not getting passed in correctly. For one, the problem dimensions between your run and mine are quite different. My guess is that come constraints that could / should be box constraints are being set as linear constraints, and that this problem has very high (ie, irrelevant) box constraints (like 1e10 or something) which is killing performance.

@stephane-caron
Copy link
Member Author

(Stashing my notes on DUALC1 here, feel free to skip this message.)

Checking the problem DUALC1 from its QPS file directly:

min            f(x) = c_0 + c^T x + 1/2 x^T Q x
subject to     lcon <= A x <= ucon
               lvar <= x <= uvar

The problem has this structure:

  • x.shape = (9,)
  • A.shape = (215, 9)
  • lvar = [0 0 0 0 0 0 0 0 0]
  • uvar = [1 1 1 1 1 1 1 1 1]
  • There is only one equality constraint: [1 1 1 1 1 1 1 1 1] x == 1
  • There is one constraint without a lower bound -infinity <= [-12., 19., 4., 4., 4., 33., 38., 67., -9.] x <= 0
  • ucon is +infinity except for the two above constraints
  • lcon is 0 except for the two above constraints

@stephane-caron
Copy link
Member Author

stephane-caron commented Nov 11, 2022

My guess is that come constraints that could / should be box constraints are being set as linear constraints, and that this problem has very high (ie, irrelevant) box constraints (like 1e10 or something) which is killing performance.

You're right 🚀

Not the box constraints which are easy in this problem, but the infinities in lcon and ucon which were converted to 1e20 in matrix files from osqp_benchmark. Those would end up in the data["b"] vector for SCS and give it a hard time. I'm not done investigating but this is likely the reason why so many problems in the test set ended up as SOLVED_INACCURATE.

I've filtered out +infinities from data["b"] and now it works 👌

$ python ./benchmark.py check_problem maros_meszaros_dense DUALC1
[2022-11-11 19:14:17,874] [info] Loading existing results from ./results/maros_meszaros_dense.csv (results.py:59)
[2022-11-11 19:14:18,147] [info] Check out `problem` for the DUALC1 problem (benchmark.py:170)
Python 3.8.10 (default, Jun 22 2022, 20:18:18) 
Type 'copyright', 'credits' or 'license' for more information
IPython 8.0.1 -- An enhanced Interactive Python. Type '?' for help.

In [1]: x, t = problem.solve(solver="scs", eps_abs=1e-4, eps_rel=1e-4, verbose=True)                                                               
------------------------------------------------------------------
	       SCS v3.2.2 - Splitting Conic Solver
	(c) Brendan O'Donoghue, Stanford University, 2012
------------------------------------------------------------------
problem:  variables n: 9, constraints m: 225
cones: 	  z: primal zero / dual free vars: 1
	  l: linear vars: 214
	  b: box cone vars: 10
settings: eps_abs: 1.0e-04, eps_rel: 1.0e-04, eps_infeas: 1.0e-07
	  alpha: 1.50, scale: 1.00e-01, adaptive_scale: 1
	  max_iters: 100000, normalize: 1, rho_x: 1.00e-06
	  acceleration_lookback: 10, acceleration_interval: 10
lin-sys:  sparse-direct-amd-qdldl
	  nnz(A): 1944, nnz(P): 45
------------------------------------------------------------------
 iter | pri res | dua res |   gap   |   obj   |  scale  | time (s)
------------------------------------------------------------------
     0| 1.07e+03  3.16e+06  6.01e+05 -6.42e+06  1.00e-01  9.85e-04 
   175| 8.89e-07  1.46e-02  3.31e-01  6.16e+03  1.00e-01  2.38e-03 
------------------------------------------------------------------
status:  solved
timings: total: 2.39e-03s = setup: 8.76e-04s + solve: 1.51e-03s
	 lin-sys: 9.76e-04s, cones: 1.10e-04s, accel: 1.00e-04s
------------------------------------------------------------------
objective = 6155.077695
------------------------------------------------------------------

The only remaining difference with your output is the use of the linear cone for one-sided inequality constraints.

@stephane-caron
Copy link
Member Author

Quick check on the Maros-Meszaros dense subset after the fix (diff, report).

@bodono
Copy link

bodono commented Nov 12, 2022

Ok great, that probably explains most of the discrepancy between your results and mine, hopefully they align more after this! Other solvers may well have been affected by this issue too so probably worth re-running any of them that were.

What to put in the box cone vs put in the linear constraint is a actually kind of an interesting open question. Overall, if the bounds are likely to be very loose, then I think that the box cone is a better choice for exactly the reason you ran into. SCS accepts infinite entries in the box cone, since it's just a projection that does nothing, so feel free to try using that if you want. Though it looks as though the performance of your run and my run are essentially identical despite using different box cones, this might not be true for other problems.

@stephane-caron
Copy link
Member Author

Updated results on the Maros-Meszaros test set after the fix (diff, report).

SCS's success rate (returns "optimal" and passes tolerance checks) is now 73% with default settings.

Overall our results are much more aligned 👍 There is still some difference: in the CSV file you shared, 130 / 138 problems (94 %) have the "optimal" return status, while on my machine it's about 121 / 138 problems (88 %). The difference is on exactly 9 problems: CONT-300, HUES-MOD, HUESTIS, QETAMACR, QFFFFF80, QGFRDXPN, QPILOTNO, QSHELL and YAO. Those problems have the "optimal" status in your results, but don't solve on my machine.

(Other than this, the problems that are unsolved both in your results and in mine are: BOYD2, OWELL20, QGROW15, QGROW22, QGROW7, STADAT1, STADAT2 and STADAT3.)

I'm not too surprised that we see some difference though, as we don't have exactly the same setup. For instance it could be due to:

  • Difference in SCS version?
  • Difference in CPU (I have a pretty old laptop)?
  • Another conversion discrepancy in the benchmark code?

I will re-run the benchmark with the other solvers as well 👌

@bodono
Copy link

bodono commented Nov 14, 2022

Yes it looks like some of those are either over the 1000 second timeout, or have actually failed to solve when I re-run them under the latest version. Some of the others should be fine though, some examples below. Possibly there is still a discrepancy in the conversion.

 - Solving HUES-MOD with solver SCS-3.0
 - Optimal objective 34824690.0
------------------------------------------------------------------
               SCS v3.2.1 - Splitting Conic Solver
        (c) Brendan O'Donoghue, Stanford University, 2012
------------------------------------------------------------------
problem:  variables n: 10000, constraints m: 10003
cones:    z: primal zero / dual free vars: 2
          b: box cone vars: 10001
settings: eps_abs: 1.0e-04, eps_rel: 1.0e-04, eps_infeas: 1.0e-18
          alpha: 1.50, scale: 1.00e-01, adaptive_scale: 1
          max_iters: 100000, normalize: 1, rho_x: 1.00e-06
          acceleration_lookback: 10, acceleration_interval: 10
lin-sys:  sparse-direct-amd-qdldl
          nnz(A): 30000, nnz(P): 10000
------------------------------------------------------------------
 iter | pri res | dua res |   gap   |   obj   |  scale  | time (s)
------------------------------------------------------------------
     0| 1.09e+03  1.28e+03  2.83e+10  1.42e+10  1.00e-01  3.95e-02
   150| 4.19e-03  4.17e-06  6.09e+00  3.48e+07  8.70e-04  1.12e-01
------------------------------------------------------------------
status:  solved
timings: total: 1.12e-01s = setup: 3.75e-02s + solve: 7.42e-02s
         lin-sys: 4.77e-02s, cones: 9.72e-03s, accel: 4.07e-03s
------------------------------------------------------------------
objective = 34824406.380090
------------------------------------------------------------------
 - Solving HUESTIS with solver SCS-3.0
 - Optimal objective 348246900000.0
------------------------------------------------------------------
               SCS v3.2.1 - Splitting Conic Solver
        (c) Brendan O'Donoghue, Stanford University, 2012
------------------------------------------------------------------
problem:  variables n: 10000, constraints m: 10003
cones:    z: primal zero / dual free vars: 2
          b: box cone vars: 10001
settings: eps_abs: 1.0e-04, eps_rel: 1.0e-04, eps_infeas: 1.0e-18
          alpha: 1.50, scale: 1.00e-01, adaptive_scale: 1
          max_iters: 100000, normalize: 1, rho_x: 1.00e-06
          acceleration_lookback: 10, acceleration_interval: 10
lin-sys:  sparse-direct-amd-qdldl
          nnz(A): 30000, nnz(P): 10000
------------------------------------------------------------------
 iter | pri res | dua res |   gap   |   obj   |  scale  | time (s)
------------------------------------------------------------------
     0| 7.90e+02  1.16e+03  8.31e+10  9.65e+10  1.00e-01  2.88e-02
   125| 2.05e-06  2.61e-06  9.32e-02  3.48e+11  9.32e-01  8.31e-02
------------------------------------------------------------------
status:  solved
timings: total: 8.32e-02s = setup: 2.76e-02s + solve: 5.56e-02s
         lin-sys: 3.55e-02s, cones: 7.07e-03s, accel: 3.40e-03s
------------------------------------------------------------------
objective = 348244638698.590332
------------------------------------------------------------------
 - Solving QETAMACR with solver SCS-3.0
 - Optimal objective 86760.37
------------------------------------------------------------------
               SCS v3.2.1 - Splitting Conic Solver
        (c) Brendan O'Donoghue, Stanford University, 2012
------------------------------------------------------------------
problem:  variables n: 688, constraints m: 1089
cones:    z: primal zero / dual free vars: 354
          b: box cone vars: 735
settings: eps_abs: 1.0e-04, eps_rel: 1.0e-04, eps_infeas: 1.0e-18
          alpha: 1.50, scale: 1.00e-01, adaptive_scale: 1
          max_iters: 100000, normalize: 1, rho_x: 1.00e-06
          acceleration_lookback: 10, acceleration_interval: 10
lin-sys:  sparse-direct-amd-qdldl
          nnz(A): 3097, nnz(P): 4447
------------------------------------------------------------------
 iter | pri res | dua res |   gap   |   obj   |  scale  | time (s)
------------------------------------------------------------------
     0| 9.63e+02  7.80e+02  1.31e+04 -1.03e+04  1.00e-01  5.59e-03
   250| 3.88e+00  2.41e+01  1.46e+03  3.75e+04  1.39e+01  3.98e-02
   500| 1.81e+00  1.24e+00  7.27e+01  4.78e+04  1.39e+01  6.88e-02
   750| 4.44e+03  8.37e+03  4.17e+04  4.78e+04  1.39e+01  9.75e-02
  1000| 1.76e+00  9.52e-01  5.90e+01  5.07e+04  1.39e+01  1.26e-01
  1250| 2.05e+00  1.25e+00  6.91e+01  5.19e+04  1.39e+01  1.55e-01
  1500| 2.38e+00  1.46e+00  8.32e+01  5.32e+04  1.39e+01  1.85e-01
  1750| 2.78e+00  1.62e+00  9.37e+01  5.47e+04  1.39e+01  2.14e-01
  2000| 3.19e+00  1.83e+00  1.07e+02  5.64e+04  1.39e+01  2.43e-01
  2250| 3.28e+00  2.08e+00  1.12e+02  5.82e+04  1.39e+01  2.71e-01
  2500| 3.57e+00  2.20e+00  1.21e+02  6.02e+04  1.39e+01  3.00e-01
  2750| 4.01e+00  2.46e+00  1.32e+02  6.25e+04  1.39e+01  3.29e-01
  3000| 4.56e+00  2.79e+00  1.48e+02  6.53e+04  1.39e+01  3.58e-01
  3250| 5.17e+00  2.97e+00  1.64e+02  6.88e+04  1.39e+01  3.88e-01
  3500| 8.03e+03  1.09e+05  7.06e+04 -5.43e+03  1.39e+01  4.1(2 res
  3750| 3.65e+00  3.11e+00  1.01e+02  7.74e+04  1.39e+01  4.51e-01
  4000| 3.02e+00  1.65e+00  7.21e+01  7.92e+04  1.39e+01  4.80e-01
  4250| 2.95e+00  1.48e+00  6.84e+01  8.08e+04  1.39e+01  5.08e-01
  4500| 3.02e+00  1.47e+00  6.86e+01  8.25e+04  1.39e+01  5.38e-01
  4750| 6.91e-01  1.08e+00  1.32e+01  8.37e+04  1.39e+01  5.67e-01
  5000| 3.15e-01  5.24e-01  7.56e+00  8.39e+04  1.39e+01  5.96e-01
  5250| 3.67e-01  3.13e-01  8.63e+00  8.40e+04  1.39e+01  6.24e-01
  5500| 3.81e-01  2.40e-01  8.38e+00  8.41e+04  1.39e+01  6.53e-01
  5750| 3.80e-01  1.99e-01  8.50e+00  8.42e+04  1.39e+01  6.82e-01
  6000| 3.73e-01  2.01e-01  8.38e+00  8.43e+04  1.39e+01  7.12e-01
  6250| 4.66e+03  6.40e+04  5.01e+03  9.08e+04  1.39e+01  7.42e-01
  6500| 3.15e-01  1.95e-01  7.58e+00  8.46e+04  1.39e+01  7.72e-01
  6750| 3.19e-01  1.89e-01  7.43e+00  8.47e+04  1.39e+01  8.00e-01
  7000| 3.30e-01  1.94e-01  7.62e+00  8.48e+04  1.39e+01  8.29e-01
  7250| 3.41e-01  1.99e-01  7.82e+00  8.49e+04  1.39e+01  8.60e-01
  7500| 3.25e-01  2.19e-01  7.48e+00  8.50e+04  1.39e+01  8.90e-01
  7750| 3.18e-01  2.05e-01  7.33e+00  8.51e+04  1.39e+01  9.18e-01
  8000| 3.12e-01  2.06e-01  7.18e+00  8.51e+04  1.39e+01  9.50e-01
  8250| 3.05e-01  1.98e-01  7.05e+00  8.52e+04  1.39e+01  9.78e-01
  8500| 3.02e-01  1.93e-01  6.99e+00  8.53e+04  1.39e+01  1.01e+00
  8750| 3.02e-01  3.85e-01  6.97e+00  8.54e+04  1.39e+01  1.04e+00
  9000| 5.96e+02  8.19e+03  1.18e+03  8.79e+04  1.39e+01  1.06e+00
  9250| 2.57e-01  1.97e-01  5.87e+00  8.56e+04  1.39e+01  1.09e+00
  9500| 2.37e-01  1.72e-01  5.53e+00  8.56e+04  1.39e+01  1.12e+00
  9750| 2.21e-01  1.60e-01  5.25e+00  8.57e+04  1.39e+01  1.15e+00
 10000| 2.08e-01  1.53e-01  5.01e+00  8.58e+04  1.39e+01  1.18e+00
 10250| 1.94e-01  1.42e-01  4.72e+00  8.58e+04  1.39e+01  1.21e+00
 10500| 1.80e-01  1.38e-01  4.33e+00  8.59e+04  1.39e+01  1.24e+00
 10750| 1.71e-01  3.28e-01  4.34e+00  8.59e+04  1.39e+01  1.26e+00
 11000| 1.45e-01  1.26e-01  3.62e+00  8.60e+04  1.39e+01  1.29e+00
 11250| 1.27e-01  1.09e-01  3.35e+00  8.60e+04  1.39e+01  1.32e+00
 11500| 1.13e-01  1.02e-01  3.07e+00  8.60e+04  1.39e+01  1.35e+00
 11750| 8.21e+02  3.67e+04  1.51e+03  9.01e+04  1.39e+01  1.38e+00
 12000| 8.79e-02  1.41e-01  2.65e+00  8.61e+04  1.39e+01  1.41e+00
 12225| 7.25e-02  8.49e-02  2.35e+00  8.61e+04  1.39e+01  1.43e+00
------------------------------------------------------------------
status:  solved
timings: total: 1.43e+00s = setup: 5.27e-03s + solve: 1.43e+00s
         lin-sys: 1.30e+00s, cones: 6.17e-02s, accel: 1.50e-02s
------------------------------------------------------------------
objective = 86139.626049
------------------------------------------------------------------

@stephane-caron
Copy link
Member Author

Intriguing! I will check those three.

@stephane-caron stephane-caron changed the title Check SCS performance on DUALC1 Check SCS performance on QETAMACR Nov 14, 2022
@stephane-caron
Copy link
Member Author

Intriguing! I will check those three.

Moved to its own issue: #41

@stephane-caron stephane-caron changed the title Check SCS performance on QETAMACR Check SCS performance on DUALC1 Jan 25, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants