Optimization of generated code

Hi,

I have osqp solver genrated code(MATLAB interface) and trying to build the code using TI tool chains. During memory allocation, my linker could not allocate the uninitialized global and static variables (.ebss) section. The reason is .ebss is of 70.866 KB and the available RAM is of 54 KB.

How can I reduce my uninitialized global variables?. Please let me know if is there any way to reduce my variables

Thanks and Regards,
Satheesh

What is the size of the problem you are generating the code for? Currently, the best way to reduce the memory footprint would be to reduce the problem size.

Hi Satheesh,

Could you tell us for which TI architecture you are trying to build OSQP? Are you compiling using CCS, makefiles or CMake?

You could try one or a combination of the following:

  • compile using floats instead of doubles
  • allocate certain arrays in external memory. you can use #pragma DATA_SECTION(var, mysection) to place some of the arrays defined in workspace.h in some section mysection. You should map mysection to the external memory in the linker command file. The largest and least used arrays would probably be csc Pdata in workspace.h, allocating the arrays of that structure in external memory shouldn’t penalize your performance much.

Please let us know about your workaround.

Hi,
Thanks for the suggestions. I will try to do the changes and let you know.

  1. I am trying build OSQP for TI Delfino microcontroller (TMS320F28379D Dual core).
  2. I am compiling using CCS.

Thanks and Regards,
Satheesh

Hi,
As you mentioned higher memory foot print is due to problem size.

I have a problem with prediction horizon of 200.
P = 602x602
q = 602x1
A = 1004x602
l = 1004x1
u = 1004x1

Thanks and Regards,
Satheesh

I assume that you are using the solver to solve an MPC type problem. Do you really need such a long horizon? If so, have you considered implementing a move blocking strategy to condense the problem slightly?

Hi paul,

  1. I am using solver for MPC type problem
  2. If I reduce my prediction horizon then in MATLAB interface solver is able to solve the problem with 25 interations but after code generation and executed on TI processor, solver is taking maximum iterations of 4000 but still solver status is -2
  3. I have implemented periodic receding horizon strategy which resulted in less memory footprint. But it also resulted in termination of solver after reaching maximum iterations after executing in TI processor

Regards,
Satheesh

It is quite surprising that the solver should behave differently when used through the matlab interface and when used via embedded export. This makes me suspect that something basic is going wrong in your process for the TI target.

Have you tried solving a very simple problem in both places to check that the behaviour is actually the same? For example, I would suggest trying to solve the problem in osqp_demo.c on both platforms and checking that the iterates agree.

Hi paul,
I have tried with one simple problem in both matlab and TI processor. I could observe the same behaviour(Though Embedded processor is taking 15 seconds of time for 25 iterations).

prediction horizon = 100
P = 302x302
q = 302x1
A = 504x302 (sparse)
l = 504x1
u = 504x1

MATLAB output
MATLAB_interface

TI processor output
TI%20processor

Different behavior can be caused by:

  • EMBEDDED=1 option: it does not update the matrices and does not update \rho.
  • check_termination=0: it never checks termination and reaches the maximum number of iterations before checking convergence.
  • DFLOATS=ON: floating point numbers instead of doubles can increase the number of iterations.

Are you using any of these three options?

Unless I am misunderstanding something, it appears that your residuals are not even close to agreement between the two versions.

My suggestion was not to try a smaller version of your problem, but rather to try a problem if trivial size like in the osqp_demo. I suggest this because you need to exclude problems that are occurring due to mistranslation of the problem data when exporting.

Hi,

  1. yes, I am using embedded = 1 by selecting the vectors as parameters. Reason behind this is the requirement of less memory footprint.
  2. check_termination is left as default i.e., 25.
  3. I am using of ‘double’ while generating the code.
    Here are my settings for code generation.
    code_gen_settings

Hi paul,

I am trying to build the osqp_demo.c on TI processor.
But there is an error

osqp_demo_error_windows_header_file

If you have exported from a windows machine but then tried to compile on a different platform, you probably need to edit some of the generated headers. Most likely it is osqp_configure.h

Please let me know what changes needs to be made in osqp_configure.h. Also, how to execute osqp_demo in matlab interface?.

Here is the code of osqp_configure

To fix the compile error, comment out the line that says #define IS_WINDOWS then compile again. Note that this will uncomment itself when you regenerate the code from Matlab, so you will need to do it every time you export the problem.

The provided osqp_demo.c problem is not currently in Matlab, but it should be simple enough to code in Matlab. Then you can export the generated workspace and compare the Matlab solver and the TI solver on the same simple problem.

Hi Saatesh,

You mentioned running OSQP on the TI board before - how did you manage to circumvent the problems with that configuration header file back then?

In any case, you will also need to disable MKL Paradiso and use the QDLDL solver instead - the TI tool chains might complain about dynamically loading the Paradiso library. Following flags should be set, all other undefined:

/* Operative system */
#define IS_LINUX

/* EMBEDDED */
#define EMBEDDED (1)

/* DFLOAT */
#define DFLOAT // use floats

/* DLONG */
#define DLONG // use long long int

In case you are compiling from scratch you will have to exclude certain folders from your build which are related to the Paradiso solver. If you would like to use the profiling features, consider replacing the timer functions in osqp/util.c - e.g. by the cycle counter your board provides (might need to initialize it before).

I suggest also allowing updates to the rho parameter based on the number of iterations, rather than on timing considerations. It is unclear to me whether time-based updates will work on your embedded platform.

Suggest setting rho_update_interval to something like 25 or 50 before exporting.

Hi,

I have compiled from the scratch and I have excluded the files from build. Currently, I do not want profiling features. Can I disable the profiling function totally?.

While generating the code I did not enable the polish argument in the solver settings.

Thanks