Question

In one step of my program I need to convolve an image. To do that I am using the functions provided by fftw3. When I run valgrind on my program I get this stack trace. My function is called convolve and it runs fftw3's fftw_plan_dft_r2c_2d two times (once on the image, once on the convolution kernel. In order to make it more readable, I removed all addresses and process IDs.

HEAP SUMMARY:
    in use at exit: 62,280 bytes in 683 blocks
  total heap usage: 178,271 allocs, 177,588 frees, 36,617,058 bytes allocated

3,304 (24 direct, 3,280 indirect) bytes in 1 blocks are definitely lost in loss record 129 of 131
   at : malloc (vg_replace_malloc.c:291)
   by : fftw_malloc_plain (in ./prog)
   by : fftw_mkapiplan (in ./prog)
   by : fftw_plan_many_dft_r2c (in ./prog)
   by : fftw_plan_dft_r2c (in ./prog)
   by : fftw_plan_dft_r2c_2d (in ./prog)
   by : convolve (freqdomain.c:199)
   by : convolve (conv.c:290)
   by : main (main.c:332)

3,304 (24 direct, 3,280 indirect) bytes in 1 blocks are definitely lost in loss record 130 of 131
   at : malloc (vg_replace_malloc.c:291)
   by : fftw_malloc_plain (in ./prog)
   by : fftw_mkapiplan (in ./prog)
   by : fftw_plan_many_dft_r2c (in ./prog)
   by : fftw_plan_dft_r2c (in ./prog)
   by : fftw_plan_dft_r2c_2d (in ./prog)
   by : convolve (freqdomain.c:203)
   by : convolve (conv.c:290)
   by : main (main.c:332)

LEAK SUMMARY:
   definitely lost: 48 bytes in 2 blocks
   indirectly lost: 6,560 bytes in 60 blocks
     possibly lost: 0 bytes in 0 blocks
   still reachable: 55,672 bytes in 621 blocks
        suppressed: 0 bytes in 0 blocks
Reachable blocks (those to which a pointer was found) are not shown.
To see them, rerun with: --leak-check=full --show-leak-kinds=all

For counts of detected and suppressed errors, rerun with: -v
ERROR SUMMARY: 3 errors from 3 contexts (suppressed: 4 from 4)

As advised by the manual, after finishing I have used fftw_free and fftw_destroy_plan. I wanted to see that is there anything I can do with this or is this an internal issue with fftw3? Since the not freed malloc is positioned deep in the FFTW source codes.

EDIT: after including fftw_cleanup()

Below you can see the diff after I added fftw_cleanup().

[me@mycomputer]$ diff NoCleanup WithCleanup 
2,3c2,3
<     in use at exit: 62,280 bytes in 683 blocks
<   total heap usage: 178,271 allocs, 177,588 frees, 36,617,058 bytes allocated
---
>     in use at exit: 9,008 bytes in 66 blocks
>   total heap usage: 178,271 allocs, 178,205 frees, 36,617,058 bytes allocated
5c5
< 3,304 (24 direct, 3,280 indirect) bytes in 1 blocks are definitely lost in loss record 129 of 131
---
> 3,304 (24 direct, 3,280 indirect) bytes in 1 blocks are definitely lost in loss record 39 of 40
16c16
< 3,304 (24 direct, 3,280 indirect) bytes in 1 blocks are definitely lost in loss record 130 of 131
---
> 3,304 (24 direct, 3,280 indirect) bytes in 1 blocks are definitely lost in loss record 40 of 40
31c31
<    still reachable: 55,672 bytes in 621 blocks
---
>    still reachable: 2,400 bytes in 4 blocks

The number of still reachable bytes in use at exit has significantly decreased, also the number of freed mallocs has increased. But the main error (3,304 (24 direct, 3,280 indirect) bytes in 1 blocks are definitely lost) still remains.

Was it helpful?

Solution 2

I believe you may have an error in your own code, but I do suggest a test to narrow down the issue.

I (randomly) found some sample code that calls fftw_plan_dft_r2c_2d() once, as well as other parts of FFTW library functions.

In my environment: amd64 based Debian 7.4 "wheezy", libfftw 3.3.2 + Debian patches (3.3.2-3.1) and gcc 4.7.2 (Debian 4.7.2-5) running this test code under valgrind appears to have no leaked memory once you explicitly add fftw_cleanup() to either the end of each test0# function or once at the end of main(), before the return.

So unless the FFTW library has a memory leak when you call fftw_plan_dft_r2c_2d() multiple times, I suspect the error is in your own code.

Feel free to adapt the sample code written by John Burkardt and licensed under LGPL to repeatedly call fftw_plan_dft_r2c_2d() if you believe there is a memory leak in the library rather than your usage of it.

OTHER TIPS

From the FFTW documentation:

FFTW's planner saves some other persistent data, such as the accumulated wisdom and a list of algorithms available in the current configuration. If you want to deallocate all of that and reset FFTW to the pristine state it was in when you started your program, you can call:

void fftw_cleanup(void);

I've found that simply calling *fftw_destroy_plan* will also remove the missing blocks messages from valgrind output.

Of course, calling *fftw_cleanup* will mop everything up.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top