cvxgrp / cvxpygen

Code generation with CVXPY

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Generate code for Variable derivative

a-latyshev opened this issue · comments

Dear cvxpygen developers,
First of all I would like to thank the developers for cvxpygen, it's a really fantastic extension, which can potentially accelerate any cvxpy code!
I'm wondering how I can generate C code for the derivate function of a cvxpy problem. I leave here the example, which I would like to convert completely into C code:

import cvxpy as cp
import numpy as np

# We can solve plasticity problems of solid mechanics with the help of cvxpy
# There is a simple example of the vonMises perfect plasticity 

sig0 = 1
E = 1
nu = 0.3
lmbda = E*nu/(1+nu)/(1-2*nu)
mu = E/2/(1+nu)
l, m = lmbda, mu

C = np.array([[l+2*m, l, l, 0],
              [l, l+2*m, l, 0],
              [l, l, l+2*m, 0],
              [0, 0, 0, 2*m]])

deps = cp.Parameter((4,), name='deps')
sig_old = cp.Parameter((4,), name='sig_old')
sig_elas = sig_old + C @ deps
sig = cp.Variable((4, ), name='sig')

obj = cp.quad_form(sig - sig_elas, np.linalg.inv(C))
problem = cp.Problem(cp.Minimize(obj), [np.sqrt(3/2)*cp.norm(sig) <= sig0])

N = 100
theta = np.linspace(0, 2*np.pi, N+1)
Eps = 0.1*np.vstack((np.cos(theta), np.sin(theta), 0*theta, 0*theta)).T
Sig = np.zeros_like(Eps)

for i in range(N + 1):
    sig_old.value = np.zeros((4, ))
    deps.value = Eps[i,:]
    
    # We can generate the corresponded C code of this solve function
    # But how can I take into account a `requires_grad` argument in cvxpygen?
    problem.solve(solver='SCS', requires_grad=True)
    Sig[i,:] = sig.value

    C_tang = np.zeros((4, 4))
    for i in range(4):
        z = np.zeros((4,))
        z[i] = 1
        # It would be a great advantage to generate appropriate C functions and variables for the following lines
        deps.delta = z
        problem.derivative()
        C_tang[i, :] = sig.delta

    # Here `C_tang` should be the same as `C`
    assert np.max(np.abs(C_tang - C)) < 1e-4

Is it possible to generate C code for this kind of problem? Can you please give some advice about how I can do it in cvxpygen?

About context. I'm interested in embedding a cvxpy solver into JIT compilable code, such as numba functions are, for instance. I considered cvxcore wrapping to implement this, but it's time-consuming and I didn’t find any C++ API… So it’s much faster with cvxpygen, which automatically generates the C-code! I wrote some kind of wrapper via the cffi library and could solve a convex problem inside a numba function. Here you can find a simple example.

If I could get a C analog of the problem.derivate() function and related cvxpy features, I would dramatically accelerate the performance of my code!

Thank you for your work!

This is the library for computing the derivatives: https://github.com/cvxgrp/diffcp
The core is in C++ I believe, wrapped with pybind.