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

Unintended heap allocations #91

Closed
fennel-labs opened this issue Nov 8, 2022 · 15 comments
Closed

Unintended heap allocations #91

fennel-labs opened this issue Nov 8, 2022 · 15 comments

Comments

@fennel-labs
Copy link
Contributor

ProxQP does a lot of work to avoid heap allocations. However, I found that some heap allocations are still performed after the initialization. Here is the call graph with the functions that allocate from the heap during solve():

callgraph

Steps to reproduce:

  • Take any QP (e.g. from testcases)
  • Compile with:
    • Eigen 3.3.4
    • -O0 -g -DNDEBUG -std=gnu++17 -DPROXSUITE_VECTORIZE
  • valgrind --tool=massif --xtree-memory=full <name_to_executable_to_examine>
  • kcachegrind <name_of_output>

Desired behavior

ProxQP does not generate any heap allocations during solve. This is essential for running ProxQP on resource-constrained devices or under real-time constraints.

@ahoarau
Copy link

ahoarau commented Nov 8, 2022

Seems to be eigen stuff. It has the nice Eigen::internal::set_is_malloc_allowed(false); function to detect runtime allocations.

With https://gitlab.com/libeigen/eigen/-/merge_requests/1055 it even supports reallocs.

@fennel-labs
Copy link
Contributor Author

It is definitely Eigen, as the lowest node of the call graph above already reveals. This means, that Eigen is used wrong or has some unknown version incompatibility with ProxQP.

@ahoarau
Copy link

ahoarau commented Nov 8, 2022

Then you can try to surround the solve() call with

Eigen::internal::set_is_malloc_allowed(false);
solver->solver();
Eigen::internal::set_is_malloc_allowed(true);

NOTE: Don't forget to compile in Debug with EIGEN_RUNTIME_NO_MALLOC defined somewhere.

@jcarpent
Copy link
Member

jcarpent commented Nov 8, 2022

@fennel-labs Thanks for raising this issue.
Could you try with Eigen 3.4.0?

@fabinsch
Copy link
Collaborator

fabinsch commented Nov 8, 2022

With @Bambade we checked the dense backend and we could find that we actually have some allocations in the dense factorize function. It fails if we set_malloc_allowed to false here.

@fennel-labs
Copy link
Contributor Author

fennel-labs commented Nov 8, 2022

I tried with 3.4.0, allocations still happen. Here is the corresponding call graph:

callgraph_Eigen3 4 0

@fabinsch You can find all relevant function names with allocations in the figure.

@jcarpent
Copy link
Member

jcarpent commented Nov 8, 2022

@fennel-labs We have fixed the heap allocations in the code in #92.
Hope it will solve your issue.

@fennel-labs
Copy link
Contributor Author

@jcarpent I can confirm, that this fixes the issue under Eigen 3.4.0. With 3.3.4 heap allocations are still observed.

@jcarpent
Copy link
Member

jcarpent commented Nov 8, 2022

Could provide the call graph for 3.3.4 after the fix?

@jcarpent
Copy link
Member

jcarpent commented Nov 8, 2022

@fennel-labs I've just updated the PR with further fixes. Should be fine hopefully.

@fennel-labs
Copy link
Contributor Author

You were a minute faster than me, here is the call graph. I will try the new changes immediately.

callgraph_Eigen3 3 4_patches

@fennel-labs
Copy link
Contributor Author

@jcarpent Some allocations are still left:
callgraph_Eigen3 3 4_patches2

@jcarpent
Copy link
Member

jcarpent commented Nov 8, 2022

@fennel-labs 2ec747d should fix the issue on Eigen 3.3.4

@fennel-labs
Copy link
Contributor Author

@jcarpent Yes, allocations are gone now for both, 3.3.4 and 3.4.0. Thank you so much!

@jcarpent
Copy link
Member

jcarpent commented Nov 8, 2022

Thanks @fennel-labs for the quick feedback. We really appreciate it.

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

4 participants