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
Your example for
parallelFor-- and indeed any use ofparallelFor- generates avalgrindmemory leak. Can be reproduced by pasting your suggested code intest.cpp, with the following three necessary lines pre-pended:Running
valgrindon a filetest.Rcontaining justvia
generates the following output
A fix would be greatly appreciated!