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

How to specify the solver in cvxpylayers #130

Open
amansouri3476 opened this issue Jun 27, 2022 · 1 comment
Open

How to specify the solver in cvxpylayers #130

amansouri3476 opened this issue Jun 27, 2022 · 1 comment

Comments

@amansouri3476
Copy link

Hi!

Thank you for this great package!

I have a simple question for which I couldn't find the answer in other issues or on the web.

If I have a simple problem like the following, for which I'm using cvxpylayers (to be able to solve a batch of optimization problems), how/where can I specify the solver? In the documents, I see that the solver is specified as an argument to problem.solve(solver='mosek'). However, when using cvxpylayers, we don't invoke solve() on the problem, rather it's done internally.

Here's my problem definition:

num_slots = 5
n_mechanisms = 3
p = num_slots ** 2
    
w = cp.Variable((n_mechanisms, p))
C = cp.Parameter((n_mechanisms, p))
# vectorized constraints
constraints = []
constraints.extend([cp.sum(w, axis=1) == np.ones((n_mechanisms,))])
constraint = []
for k in range(num_slots):
    temp_mask = np.zeros((n_mechanisms, p))
    for i in range(n_mechanisms):
        for j in range(k*num_slots, (k+1)*num_slots):
            temp_mask[i,j] = 1.0
    
    temp_mask = (temp_mask == 1.0)
    constraint.append(cp.sum(w[temp_mask]))
constraint = cp.vstack(constraint)
constraints.extend([constraint <= np.ones((num_slots, 1))])
constraint = []
for k in range(num_slots):
    temp_mask = np.zeros((n_mechanisms, p))
    for i in range(n_mechanisms):
        for j in range(k, p, num_slots):
            temp_mask[i,j] = 1.0
    temp_mask = (temp_mask == 1.0)
    constraint.append(cp.sum(w[temp_mask]))
    
constraint = cp.vstack(constraint)
constraints.extend([constraint <= np.ones((num_slots, 1))])
constraints.extend([w >= 0.001])
constraints.extend([w <= 1.0])
# problem: objective and the problem:
objective = cp.Minimize(cp.sum(cp.multiply(w, C))**2)
problem = cp.Problem(objective, constraints)
assert problem.is_dpp()
cvxpylayer = CvxpyLayer(problem, parameters=[C], variables=[w])

Additionally, I would very much appreciate it if one could advise me as to whether my problem definition adheres to best practices for using cvxpy. I've reformulated my problem a couple of times to get speed-ups, and to me, this seems the closest form to defining a set of vectorized constraints. In fact when I remove all constraints, except for constraints.extend([w >= 0.001]), it only gets slower by about 20%, so I'm not sure if there's much room for improvement. But for my application, it is still slow, and each batch of size 128 still takes about 1s with 40 CPU cores. If I increase the problem size, it easily gets to 7s or 10s per batch which is considered very slow for my use case. I would very much appreciate any advice on speeding it up.

Many thanks for your time and support.

@XFeiF
Copy link

XFeiF commented Oct 26, 2022

First, until 2022, CVXPY Layer supports two open-source solvers: SCS and ECOS. More details can be found in issue #51 .

Besides, CVXPY Layers uses the package diffcp to differentiate through cone programs. Right now, diffcp only supports SCS... Once diffcp supports (say) MOSEK, CVXPY Layers could support it as well.

To specify the solver, you need to pass solver_args={"solve_method":"ECOS"} to your cvxpylayer.

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