Dear Martin, Many thanks for your reply, it was really helpful. My collaborator ran the commands you suggested and got the following output:
***** $ Rscript norm_laplacian.R /home/jake/miniconda3/lib/R/bin/R CMD SHLIB -o 'sourceCpp_2.so' 'norm_laplacian.cpp' g++ -I/home/jake/miniconda3/lib/R/include -DNDEBUG -I/home/jake/miniconda3/include -I"/home/jake/R/x86_64-pc-linux-gnu-library/3.3/Rcpp/include" -I"/home/jake/R/x86_64-pc-linux-gnu-library/3.3/RcppArmadillo/include" -I"/home/jake/Documents" -fpic -I/home/jake/miniconda3/include -c norm_laplacian.cpp -o norm_laplacian.o g++ -shared -L/home/jake/miniconda3/lib/R/lib -L/home/jake/miniconda3/lib -lgfortran -o sourceCpp_2.so norm_laplacian.o -L/home/jake/miniconda3/lib/R/lib -lRlapack -L/home/jake/miniconda3/lib/R/lib -lRblas -lgfortran -lm -lquadmath -L/home/jake/miniconda3/lib/R/lib -lR R version 3.3.2 (2016-10-31) Platform: x86_64-pc-linux-gnu (64-bit) Running under: Ubuntu 16.10 locale: [1] LC_CTYPE=en_US.UTF-8 LC_NUMERIC=C [3] LC_TIME=en_US.UTF-8 LC_COLLATE=en_US.UTF-8 [5] LC_MONETARY=en_US.UTF-8 LC_MESSAGES=en_US.UTF-8 [7] LC_PAPER=en_US.UTF-8 LC_NAME=C [9] LC_ADDRESS=C LC_TELEPHONE=C [11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C attached base packages: [1] stats graphics grDevices utils datasets base other attached packages: [1] Rcpp_0.12.8 loaded via a namespace (and not attached): [1] tools_3.3.2 RcppArmadillo_0.7.600.1.0 $ g++ --version|head -n1 g++ (Ubuntu 6.2.0-5ubuntu12) 6.2.0 20161005 ***** So running the simplified code did not produce a segfault and suggested that the problem was in SC3::norm_laplacian(). And indeed, running valgrind with SC3::norm_laplacian(matrix(runif(100), nrow = 10)) did catch the error: ***** $ R -d valgrind -f norm_laplacian.R ==7046== Memcheck, a memory error detector ==7046== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al. ==7046== Using Valgrind-3.12.0.SVN and LibVEX; rerun with -h for copyright info ==7046== Command: /home/jake/miniconda3/lib/R/bin/exec/R -f norm_laplacian.R ==7046== R version 3.3.2 (2016-10-31) -- "Sincere Pumpkin Patch" Copyright (C) 2016 The R Foundation for Statistical Computing Platform: x86_64-pc-linux-gnu (64-bit) > library(Rcpp) > sourceCpp("norm_laplacian.cpp", showOutput=TRUE) /home/jake/miniconda3/lib/R/bin/R CMD SHLIB -o 'sourceCpp_2.so' 'norm_laplacian.cpp' g++ -I/home/jake/miniconda3/lib/R/include -DNDEBUG -I/home/jake/miniconda3/include -I"/home/jake/R/x86_64-pc-linux-gnu-library/3.3/Rcpp/include" -I"/home/jake/R/x86_64-pc-linux-gnu-library/3.3/RcppArmadillo/include" -I"/home/jake/Documents" -fpic -I/home/jake/miniconda3/include -c norm_laplacian.cpp -o norm_laplacian.o g++ -shared -L/home/jake/miniconda3/lib/R/lib -L/home/jake/miniconda3/lib -lgfortran -o sourceCpp_2.so norm_laplacian.o -L/home/jake/miniconda3/lib/R/lib -lRlapack -L/home/jake/miniconda3/lib/R/lib -lRblas -lgfortran -lm -lquadmath -L/home/jake/miniconda3/lib/R/lib -lR > xx <- norm_laplacian(matrix(runif(100), nrow = 10)) > SC3::norm_laplacian(matrix(runif(100), nrow = 10)) ==7046== Use of uninitialised value of size 8 ==7046== at 0x213645B8: direct_max<double> (op_max_meat.hpp:362) ==7046== by 0x213645B8: max (Mat_meat.hpp:6801) ==7046== by 0x213645B8: norm_laplacian(arma::Mat<double>) (cppFunctions.cpp:87) ==7046== by 0x21360E8C: SC3_norm_laplacian (RcppExports.cpp:49) ==7046== by 0x521DE81: R_doDotCall (in /home/jake/miniconda3/lib/R/lib/libR.so) ==7046== by 0x522BD99: do_dotcall (in /home/jake/miniconda3/lib/R/lib/libR.so) ==7046== by 0x5267AAC: Rf_eval (in /home/jake/miniconda3/lib/R/lib/libR.so) ==7046== by 0x526B0A7: do_begin (in /home/jake/miniconda3/lib/R/lib/libR.so) ==7046== by 0x526789E: Rf_eval (in /home/jake/miniconda3/lib/R/lib/libR.so) ==7046== by 0x5268B8C: Rf_applyClosure (in /home/jake/miniconda3/lib/R/lib/libR.so) ==7046== by 0x5267BBF: Rf_eval (in /home/jake/miniconda3/lib/R/lib/libR.so) ==7046== by 0x52A6C1E: Rf_ReplIteration (in /home/jake/miniconda3/lib/R/lib/libR.so) ==7046== by 0x52A6DD1: R_ReplConsole (in /home/jake/miniconda3/lib/R/lib/libR.so) ==7046== by 0x52A8758: run_Rmainloop (in /home/jake/miniconda3/lib/R/lib/libR.so) ==7046== ==7046== Invalid read of size 8 ==7046== at 0x213645B8: direct_max<double> (op_max_meat.hpp:362) ==7046== by 0x213645B8: max (Mat_meat.hpp:6801) ==7046== by 0x213645B8: norm_laplacian(arma::Mat<double>) (cppFunctions.cpp:87) ==7046== by 0x21360E8C: SC3_norm_laplacian (RcppExports.cpp:49) ==7046== by 0x521DE81: R_doDotCall (in /home/jake/miniconda3/lib/R/lib/libR.so) ==7046== by 0x522BD99: do_dotcall (in /home/jake/miniconda3/lib/R/lib/libR.so) ==7046== by 0x5267AAC: Rf_eval (in /home/jake/miniconda3/lib/R/lib/libR.so) ==7046== by 0x526B0A7: do_begin (in /home/jake/miniconda3/lib/R/lib/libR.so) ==7046== by 0x526789E: Rf_eval (in /home/jake/miniconda3/lib/R/lib/libR.so) ==7046== by 0x5268B8C: Rf_applyClosure (in /home/jake/miniconda3/lib/R/lib/libR.so) ==7046== by 0x5267BBF: Rf_eval (in /home/jake/miniconda3/lib/R/lib/libR.so) ==7046== by 0x52A6C1E: Rf_ReplIteration (in /home/jake/miniconda3/lib/R/lib/libR.so) ==7046== by 0x52A6DD1: R_ReplConsole (in /home/jake/miniconda3/lib/R/lib/libR.so) ==7046== by 0x52A8758: run_Rmainloop (in /home/jake/miniconda3/lib/R/lib/libR.so) ==7046== Address 0xa0000000a is not stack'd, malloc'd or (recently) free'd ==7046== *** caught segfault *** address 0xa0000000a, cause 'memory not mapped' Traceback: 1: .Call("SC3_norm_laplacian", PACKAGE = "SC3", A) 2: SC3::norm_laplacian(matrix(runif(100), nrow = 10)) An irrecoverable exception occurred. R is aborting now ... ==7046== ==7046== Process terminating with default action of signal 11 (SIGSEGV) ==7046== at 0x5C4C4DD: raise (raise.c:53) ==7046== by 0x52A76C4: sigactionSegv (in /home/jake/miniconda3/lib/R/lib/libR.so) ==7046== by 0x5C4C62F: ??? (in /lib/x86_64-linux-gnu/libpthread-2.24.so) ==7046== by 0x213645B7: direct_max<double> (op_max_meat.hpp:360) ==7046== by 0x213645B7: max (Mat_meat.hpp:6801) ==7046== by 0x213645B7: norm_laplacian(arma::Mat<double>) (cppFunctions.cpp:87) ==7046== ==7046== HEAP SUMMARY: ==7046== in use at exit: 149,681,035 bytes in 81,447 blocks ==7046== total heap usage: 275,293 allocs, 193,846 frees, 410,601,938 bytes allocated ==7046== ==7046== LEAK SUMMARY: ==7046== definitely lost: 0 bytes in 0 blocks ==7046== indirectly lost: 0 bytes in 0 blocks ==7046== possibly lost: 0 bytes in 0 blocks ==7046== still reachable: 149,681,035 bytes in 81,447 blocks ==7046== of which reachable via heuristic: ==7046== newarray : 7,152 bytes in 1 blocks ==7046== suppressed: 0 bytes in 0 blocks ==7046== Rerun with --leak-check=full to see details of leaked memory ==7046== ==7046== For counts of detected and suppressed errors, rerun with: -v ==7046== Use --track-origins=yes to see where uninitialised values come from ==7046== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0) Segmentation fault (core dumped) ***** So, it looks like the problem is in finding the max of the input matrix A, specifically in the direct_max() function of Armadillo library. But the segfault only appears when running SC3::norm_laplacian() and not the simplified code. Does it suggest that I have some linking or exporting problems in the package? Can you think of any solution to this problem? In case this can help, the SC3::norm_laplacian() function is stored in the file with the following header: #include <armadillo> #include <RcppArmadillo.h> using namespace arma; using namespace Rcpp; Many thanks in advance, Kind regards, Vladimir On Thu, Jan 5, 2017 at 12:19 PM Martin Morgan <martin.mor...@roswellpark.org> wrote: > On 01/05/2017 06:41 AM, Vladimir Kiselev wrote: > > My package (SC3 - > http://bioconductor.org/packages/3.4/bioc/html/SC3.html) > > has a function that causes R version/platform-dependent seqfault. Here is > > the function (it's in C++ using RccpArmadillo): > > > > arma::mat norm_laplacian(arma::mat A) { > > A = exp(-A/A.max()); > > arma::rowvec D_row = pow(sum(A), -0.5); > > A.each_row() %= D_row; > > colvec D_col = conv_to< colvec >::from(D_row); > > A.each_col() %= D_col; > > arma::mat res = eye(A.n_cols, A.n_cols) - A; > > return(res); > > } > > > > The test code that provides a segfault on some R versions/platforms: > > SC3::norm_laplacian(matrix(runif(100), nrow = 10)) > > The first line of attack is to simplify the problem as much as possible. > I did this by writing a C++ file norm_laplacian.cpp > > #include <RcppArmadillo.h> > > using namespace arma; > > // [[Rcpp::depends(RcppArmadillo)]] > > // [[Rcpp::export]] > arma::mat norm_laplacian(arma::mat A) { > A = exp(-A/A.max()); > arma::rowvec D_row = pow(sum(A), -0.5); > A.each_row() %= D_row; > colvec D_col = conv_to< colvec >::from(D_row); > A.each_col() %= D_col; > arma::mat res = eye(A.n_cols, A.n_cols) - A; > return(res); > } > > and then in R, e.g., norm_laplacian.R > > library(Rcpp) > sourceCpp("norm_laplacian.cpp", showOutput=TRUE) > xx <- norm_laplacian(matrix(runif(100), nrow = 10)) > sessionInfo() > > It would be helpful to use set.seed() to make the example more > reproducible. One would hope that > > R -f norm_laplacian.R > > would produce a segfault. Unfortunately not for me. My next step was to > run this code under valgrind to look for invalid memory access > > R -d valgrind -f norm_laplacian.R > > again hoping for a report of 'invalid write' or 'invalid read', but > again no luck for me. > > You could see if your collaborators are able to generate segfaults with > this simpler code. If R -f norm_laplacian.R is sufficient, the next step > would be to run it under a C-level debugger like gdb, with some hints at > http://bioconductor.org/developers/how-to/c-debugging/ > > Here's my output; it's also useful to know information about the > compiler, and to pay attention to the compiler options (especially > optimization level -O0 for me) > > $ g++ --version|head -n1 > g++ (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609 > > $ R --vanilla -f norm_laplacian.R > > library(Rcpp) > > sourceCpp("norm_laplacian.cpp", showOutput=TRUE) > /home/mtmorgan/bin/R-devel/bin/R CMD SHLIB -o 'sourceCpp_2.so' > 'norm_laplacian.cpp' > g++ -I/home/mtmorgan/bin/R-devel/include -DNDEBUG -I/usr/local/include > > -I"/home/mtmorgan/R/x86_64-pc-linux-gnu-library/3.4-Bioc-3.5/Rcpp/include" > > -I"/home/mtmorgan/R/x86_64-pc-linux-gnu-library/3.4-Bioc-3.5/RcppArmadillo/include" > -I"/tmp" -fpic -g -O0 -c norm_laplacian.cpp -o norm_laplacian.o > g++ -shared -L/home/mtmorgan/bin/R-devel/lib -L/usr/local/lib -o > sourceCpp_2.so norm_laplacian.o -L/home/mtmorgan/bin/R-devel/lib > -lRlapack -L/home/mtmorgan/bin/R-devel/lib -lRblas -lgfortran -lm > -lquadmath -L/home/mtmorgan/bin/R-devel/lib -lR > > xx <- norm_laplacian(matrix(runif(100), nrow = 10)) > > sessionInfo() > R Under development (unstable) (2016-12-20 r71827) > Platform: x86_64-pc-linux-gnu (64-bit) > Running under: Ubuntu 16.04.1 LTS > > locale: > [1] LC_CTYPE=en_US.UTF-8 LC_NUMERIC=C > [3] LC_TIME=en_US.UTF-8 LC_COLLATE=en_US.UTF-8 > [5] LC_MONETARY=en_US.UTF-8 LC_MESSAGES=en_US.UTF-8 > [7] LC_PAPER=en_US.UTF-8 LC_NAME=C > [9] LC_ADDRESS=C LC_TELEPHONE=C > [11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C > > attached base packages: > [1] stats graphics grDevices utils datasets methods base > > other attached packages: > [1] Rcpp_0.12.8.3 > > loaded via a namespace (and not attached): > [1] compiler_3.4.0 tools_3.4.0 > [3] RcppArmadillo_0.7.600.1.0 > > > > > if the segfault does not occur with the simpler code, then one could try > gdb / valgrind with SC3::norm_laplacian(matrix(runif(100), nrow = 10)) > > Martin > > > > > The segfault usually looks like this: > > *** caught segfault *** > > address 0x7ffdc981e000, cause 'memory not mapped' > > > > (where address can be a different sequence) > > > > So far by a collaborative effort (me and some users of the package) we > > figured out configurations that cause or do not cause a segfault: > > > > * Configurations causing a segfault: > > > > R version 3.3.2 (2016-10-31) > > Platform: x86_64-pc-linux-gnu (64-bit) > > Running under: Arch Linux > > > > R version 3.3.2 (2016-10-31) > > Platform: x86_64-pc-linux-gnu (64-bit) > > Running under: Ubuntu 16.10 > > > > * Configurations causing no segfault: > > > > R version 3.3.2 (2016-10-31) > > Platform: x86_64-pc-linux-gnu (64-bit) > > Running under: Ubuntu 16.04.1 LTS > > > > R version 3.3.1 (2016-06-21) > > Platform: x86_64-pc-linux-gnu (64-bit) > > Running under: Ubuntu 14.04.5 LTS > > > > R version 3.3.0 (2016-05-03) > > Platform: x86_64-pc-linux-gnu (64-bit) > > Running under: Ubuntu precise (12.04.5 LTS) > > > > R Under development (unstable) (2016-10-20 r71540) > > Platform: x86_64-apple-darwin13.4.0 (64-bit) > > Running under: OS X Yosemite 10.10.5 > > > > More details on our discussion can be found here: > > https://github.com/hemberg-lab/SC3/issues/33 > > > > Has anybody had a similar issue? Do you have any suggestions on how to > fix > > this, except rewriting the function in R? Or maybe there already exists a > > normalised Laplacian function written in C++? > > > > Many thanks, > > Cheers, > > Vladimir > > > > > This email message may contain legally privileged and/or confidential > information. If you are not the intended recipient(s), or the employee or > agent responsible for the delivery of this message to the intended > recipient(s), you are hereby notified that any disclosure, copying, > distribution, or use of this email message is prohibited. If you have > received this message in error, please notify the sender immediately by > e-mail and delete this email message from your computer. Thank you. > -- http://genat.uk [[alternative HTML version deleted]] _______________________________________________ Bioc-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/bioc-devel