Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Memory leak with Eigen + std::vector + OpenMP [duplicate]

I have a problem with Eigen that is driving me crazy. I keep getting memory leaks from valgrind whenever I try to re-assign a set of Eigen::MatrixXd which are stored in a std::vector.

I've rewritten my code at least 5 times, I've tried with std::maps (which were part of my initial solution), I've moved from vectors of vectors to plain vectors.... Nothing worked. As soon as I add my openMP directive, I get the leaks.

Here's a minimal working example:

#include <iostream>
#include <Eigen/Dense>
#include <vector>
#include <omp.h>

typedef Eigen::Matrix< float, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor > EMat;

EMat function() {
        EMat a(19,29);
        return a;
}

int main() {
        std::vector < EMat > v(10);

#pragma omp parallel for schedule(dynamic)
        for (unsigned int i = 0; i < 10; ++i) {
                v[i] = function();
        }
}

If I try to run it with valgrind, I get:

r@darkstar ~/tmp $ valgrind --leak-check=full --show-leak-kinds=all ./test_leak==9640== Memcheck, a memory error detector
==9640== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==9640== Using Valgrind-3.10.0.SVN and LibVEX; rerun with -h for copyright info
==9640== Command: ./test_leak
==9640== 
==9640== 
==9640== HEAP SUMMARY:
==9640==     in use at exit: 4,632 bytes in 10 blocks
==9640==   total heap usage: 31 allocs, 21 frees, 48,952 bytes allocated
==9640== 
==9640== 72 bytes in 1 blocks are still reachable in loss record 1 of 4
==9640==    at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==9640==    by 0x4C2CF1F: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==9640==    by 0x513F7F8: gomp_realloc (alloc.c:54)
==9640==    by 0x51439FA: gomp_team_start (team.c:376)
==9640==    by 0x51412E9: GOMP_parallel_loop_dynamic_start (loop.c:466)
==9640==    by 0x400EBD: main (test_leak.cpp:19)
==9640== 
==9640== 192 bytes in 1 blocks are still reachable in loss record 2 of 4
==9640==    at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==9640==    by 0x513F7A8: gomp_malloc (alloc.c:36)
==9640==    by 0x5143B8E: gomp_team_start (team.c:190)
==9640==    by 0x51412E9: GOMP_parallel_loop_dynamic_start (loop.c:466)
==9640==    by 0x400EBD: main (test_leak.cpp:19)
==9640== 
==9640== 2,128 bytes in 7 blocks are possibly lost in loss record 3 of 4
==9640==    at 0x4C2CC70: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==9640==    by 0x4012E54: _dl_allocate_tls (dl-tls.c:296)
==9640==    by 0x5C33DA0: pthread_create@@GLIBC_2.2.5 (allocatestack.c:589)
==9640==    by 0x5143905: gomp_team_start (team.c:439)
==9640==    by 0x51412E9: GOMP_parallel_loop_dynamic_start (loop.c:466)
==9640==    by 0x400EBD: main (test_leak.cpp:19)
==9640== 
==9640== 2,240 bytes in 1 blocks are still reachable in loss record 4 of 4
==9640==    at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==9640==    by 0x513F7A8: gomp_malloc (alloc.c:36)
==9640==    by 0x51434D5: gomp_new_team (team.c:144)
==9640==    by 0x51405FC: gomp_parallel_loop_start (loop.c:447)
==9640==    by 0x51412E9: GOMP_parallel_loop_dynamic_start (loop.c:466)
==9640==    by 0x400EBD: main (test_leak.cpp:19)
==9640== 
==9640== LEAK SUMMARY:
==9640==    definitely lost: 0 bytes in 0 blocks
==9640==    indirectly lost: 0 bytes in 0 blocks
==9640==      possibly lost: 2,128 bytes in 7 blocks
==9640==    still reachable: 2,504 bytes in 3 blocks
==9640==         suppressed: 0 bytes in 0 blocks
==9640== 
==9640== For counts of detected and suppressed errors, rerun with: -v
==9640== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)

I've spent hours searching on the net and experimenting but with no luck. Can anyone help me please?

Thanks in advance!

R

like image 577
RH6 Avatar asked Oct 25 '25 15:10

RH6


1 Answers

It is not because of Eigen nor std::vector but because of OpenMP which "leaks" or rather valgrind report is not "trustable".

As said, do not spend too much time on this, you are not responsible of these leaks.

See related links :

  • does openmp allocate memory and free all after

As far as I can tell libgomp does not kill it's spawned threads at the end of execution and makes the kernel clean up do this.

  • gomp contains small memoryleak

In libgomp case, most of the allocations still reachable at exit time fall into the category where they really can't be freed.

like image 87
coincoin Avatar answered Oct 27 '25 06:10

coincoin