Skip to content

valgrind memory leak from parallelFor #81

Description

@mpadge

Your example for parallelFor -- and indeed any use of parallelFor - generates a valgrind memory leak. Can be reproduced by pasting your suggested code in test.cpp, with the following three necessary lines pre-pended:

#include <algorithm> // std::transform

#include <Rcpp.h>
using namespace Rcpp;

Running valgrind on a file test.R containing just

Rcpp::sourceCpp ("test.cpp")
x <- parallelMatrixSqrt (matrix (1:100, nrow = 10))

via

R -d "valgrind --tool=memcheck --leak-check=full" -f test.R

generates the following output

==3116==
==3116== HEAP SUMMARY:
==3116==     in use at exit: 53,081,616 bytes in 10,368 blocks
==3116==   total heap usage: 35,858 allocs, 25,490 frees, 93,680,163 bytes allocated
==3116==
==3116== 640 bytes in 2 blocks are possibly lost in loss record 163 of 1,639
==3116==    at 0x4839B65: calloc (vg_replace_malloc.c:752)
==3116==    by 0x40128D2: allocate_dtv (in /usr/lib/ld-2.28.so)
==3116==    by 0x4013281: _dl_allocate_tls (in /usr/lib/ld-2.28.so)
==3116==    by 0x4D08698: pthread_create@@GLIBC_2.2.5 (in /usr/lib/libpthread-2.28.so)
==3116==    by 0xE8F8D64: launch (thread_monitor.h:221)
==3116==    by 0xE8F8D64: wake_or_launch (private_server.cpp:300)
==3116==    by 0xE8F8D64: tbb::internal::rml::private_server::wake_some(int) (private_server.cpp:394)
==3116==    by 0xE90144A: tbb::internal::generic_scheduler::local_spawn(tbb::task*, tbb::task*&) (scheduler.cpp:648)
==3116==    by 0xC77F37E: tbb::interface9::internal::start_for<tbb::blocked_range<unsigned long>, RcppParallel::(anonymous
namespace)::TBBWorker, tbb::auto_partitioner const>::execute() (in
/tmp/Rtmp4ECf2u/sourceCpp-x86_64-pc-linux-gnu-0.12.19/sourcecpp_c2c5511ea5e/sourceCpp_2.so)
==3116==    by 0xE90473C: tbb::internal::custom_scheduler<tbb::internal::IntelSchedulerTraits>::local_wait_for_all(tbb::task&, tbb::task*)
(custom_scheduler.h:509)
==3116==    by 0xE901BF8: tbb::internal::generic_scheduler::local_spawn_root_and_wait(tbb::task*, tbb::task*&) (scheduler.cpp:670)
==3116==    by 0xC780037: RcppParallel::tbbParallelFor(unsigned long, unsigned long, RcppParallel::Worker&, unsigned long) (in
/tmp/Rtmp4ECf2u/sourceCpp-x86_64-pc-linux-gnu-0.12.19/sourcecpp_c2c5511ea5e/sourceCpp_2.so)
==3116==    by 0xC77EC2B: parallelMatrixSqrt(Rcpp::Matrix<14, Rcpp::PreserveStorage>) (in
/tmp/Rtmp4ECf2u/sourceCpp-x86_64-pc-linux-gnu-0.12.19/sourcecpp_c2c5511ea5e/sourceCpp_2.so)
==3116==    by 0xC77EE08: sourceCpp_1_parallelMatrixSqrt (in
/tmp/Rtmp4ECf2u/sourceCpp-x86_64-pc-linux-gnu-0.12.19/sourcecpp_c2c5511ea5e/sourceCpp_2.so)
==3116==
==3116== 1,600 bytes in 5 blocks are possibly lost in loss record 213 of 1,639
==3116==    at 0x4839B65: calloc (vg_replace_malloc.c:752)
==3116==    by 0x40128D2: allocate_dtv (in /usr/lib/ld-2.28.so)
==3116==    by 0x4013281: _dl_allocate_tls (in /usr/lib/ld-2.28.so)
==3116==    by 0x4D08698: pthread_create@@GLIBC_2.2.5 (in /usr/lib/libpthread-2.28.so)
==3116==    by 0xE8F8D64: launch (thread_monitor.h:221)
==3116==    by 0xE8F8D64: wake_or_launch (private_server.cpp:300)
==3116==    by 0xE8F8D64: tbb::internal::rml::private_server::wake_some(int) (private_server.cpp:394)
==3116==    by 0xE8F9087: propagate_chain_reaction (private_server.cpp:161)
==3116==    by 0xE8F9087: tbb::internal::rml::private_worker::run() (private_server.cpp:261)
==3116==    by 0xE8F9109: tbb::internal::rml::private_worker::thread_routine(void*) (private_server.cpp:223)
==3116==    by 0x4D07A9C: start_thread (in /usr/lib/libpthread-2.28.so)
==3116==    by 0x4E1CA42: clone (in /usr/lib/libc-2.28.so)
==3116==
==3116== LEAK SUMMARY:
==3116==    definitely lost: 0 bytes in 0 blocks
==3116==    indirectly lost: 0 bytes in 0 blocks
==3116==      possibly lost: 2,240 bytes in 7 blocks
==3116==    still reachable: 53,079,376 bytes in 10,361 blocks
==3116==                       of which reachable via heuristic:
==3116==                         newarray           : 7,360 bytes in 4 blocks
==3116==         suppressed: 0 bytes in 0 blocks
==3116== Reachable blocks (those to which a pointer was found) are not shown.
==3116== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==3116==
==3116== For counts of detected and suppressed errors, rerun with: -v
==3116== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)

A fix would be greatly appreciated!

> sessionInfo()
R version 3.5.1 (2018-07-02)
Platform: x86_64-pc-linux-gnu (64-bit)
Running under: Arch Linux

Matrix products: default
BLAS: /usr/lib/libblas.so.3.8.0
LAPACK: /usr/lib/liblapack.so.3.8.0

locale:
 [1] LC_CTYPE=en_GB.UTF-8       LC_NUMERIC=C
 [3] LC_TIME=en_GB.UTF-8        LC_COLLATE=en_GB.UTF-8
 [5] LC_MONETARY=en_GB.UTF-8    LC_MESSAGES=en_GB.UTF-8
 [7] LC_PAPER=en_GB.UTF-8       LC_NAME=C
 [9] LC_ADDRESS=C               LC_TELEPHONE=C
 [11] LC_MEASUREMENT=en_GB.UTF-8 LC_IDENTIFICATION=C

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base

loaded via a namespace (and not attached):
[1] compiler_3.5.1 tools_3.5.1    colorout_1.2-0 curl_3.2

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions