I've read related posts here and here, and looked at Dirk Eddelbuettel's talk here and yet I'm failing to even get a .log file from gperftools
. Here is my R
file, called Rcpp_practice.R
:
library(Rcpp)
Sys.setenv("PKG_LIBS"="-lprofiler")
sourceCpp('eigen.cpp')
a <- matrix(rnorm(300^2), 300, 300)
getEigenValues(a)
Here are the contents of eigen.cpp
:
#include <RcppArmadillo.h>
#include <gperftools/profiler.h>
// [[Rcpp::depends(RcppArmadillo)]]
// [[Rcpp::export]]
arma::vec getEigenValues(arma::mat M) {
return arma::eig_sym(M);
}
Then, on Terminal (I'm using OSX):
CPUPROFILE="eigenprof.log" R -f "Rcpp_practice.R"
I was hoping to see eigenprof.log
sitting in my working directory but I don't. Also, I don't get the message that I've seen in other posts of the form PROFILE: interrupts/evictions/bytes = 012/34/567891
I verified that I have the latest version of gperftools
installed. ($ brew upgrade google-perftools
gives Error: gperftools 2.5 already installed
).
What am I missing?
Update
After I modified my code to match @nrussell's I get this error message:
Error in dyn.load("/private/var/folders/6k/ffcchdq52kbb7d631b5vsqcw0000gn/T/RtmpCIdHkG/sourceCpp-x86_64-apple-darwin13.4.0-0.12.7/sourcecpp_6c3253d60384/sourceCpp_2.so") :
unable to load shared object '/private/var/folders/6k/ffcchdq52kbb7d631b5vsqcw0000gn/T/RtmpCIdHkG/sourceCpp-x86_64-apple-darwin13.4.0-0.12.7/sourcecpp_6c3253d60384/sourceCpp_2.so':
dlopen(/private/var/folders/6k/ffcchdq52kbb7d631b5vsqcw0000gn/T/RtmpCIdHkG/sourceCpp-x86_64-apple-darwin13.4.0-0.12.7/sourcecpp_6c3253d60384/sourceCpp_2.so, 6): Symbol not found: _ProfilerStart
Referenced from: /private/var/folders/6k/ffcchdq52kbb7d631b5vsqcw0000gn/T/RtmpCIdHkG/sourceCpp-x86_64-apple-darwin13.4.0-0.12.7/sourcecpp_6c3253d60384/sourceCpp_2.so
Expected in: flat namespace
in /private/var/folders/6k/ffcchdq52kbb7d631b5vsqcw0000gn/T/RtmpCIdHkG/sourceCpp-x86_64-apple-darwin13.4.0-0.12.7/sourcecpp_6c3253d60384/sourceCpp_2.so
Calls: sourceCpp -> source -> withVisible -> eval -> eval -> dyn.load
Execution halted
This appears on the line with sourceCpp
if I run the script interactively.
I don't have access to an OS X machine, but the following worked on Debian 8, where I've just added in the ProfilerStart
/ ProfilerStop
calls to your C++ code (and not changed your R code at all¹):
// [[Rcpp::depends(RcppArmadillo)]]
#include <RcppArmadillo.h>
#include <gperftools/profiler.h>
// [[Rcpp::export]]
arma::vec getEigenValues(arma::mat M) {
ProfilerStart("./eigen-prof.log");
return arma::eig_sym(M);
ProfilerStop();
}
¹See update below.
Then from a terminal,
R -f eigen-prof.R > /dev/null && google-pprof --text $(which R) eigen-prof.log
# PROFILE: interrupts/evictions/bytes = 2/0/264
# Using local file /usr/local/bin/R.
# Using local file eigen-prof.log.
# /usr/bin/addr2line: /usr/local/bin/R: File format not recognized
# Total: 2 samples
# 1 50.0% 50.0% 1 50.0% dlamch_
# 1 50.0% 100.0% 1 50.0% dsymv_
# 0 0.0% 100.0% 1 50.0% 00000000004007ca
# 0 0.0% 100.0% 1 50.0% 00000000004007fa
# 0 0.0% 100.0% 1 50.0% 00007f84002bf0bd
# 0 0.0% 100.0% 1 50.0% 00007f84002bf2a8
# 0 0.0% 100.0% 1 50.0% 00007f84002c14c8
# 0 0.0% 100.0% 1 50.0% R_ReplConsole
# 0 0.0% 100.0% 1 50.0% Rf_ReplIteration
# 0 0.0% 100.0% 1 50.0% Rf_applyClosure
# 0 0.0% 100.0% 1 50.0% Rf_eval
# 0 0.0% 100.0% 1 50.0% __libc_start_main
# 0 0.0% 100.0% 1 50.0% dlatrd_
# 0 0.0% 100.0% 1 50.0% do_dotcall
# 0 0.0% 100.0% 1 50.0% dsyev_
# 0 0.0% 100.0% 1 50.0% dsytrd_
# 0 0.0% 100.0% 1 50.0% frame_dummy
# 0 0.0% 100.0% 1 50.0% run_Rmainloop
Regarding your updates, try changing the sourceCpp
call to
sourceCpp(
'eigen-prof.cpp',
verbose = TRUE,
rebuild = TRUE,
cacheDir = "/tmp/profdir"
)
where I'm using cacheDir = "/tmp/profdir"
to override the default random directory (tempdir()
) that sourceCpp
uses to build the shared library; and rebuild = TRUE
to ensure that a new .so
is generated each run.
Back in your shell, run these commands, substituting the appropriate file & directory names as needed:
R -f eigen-prof.R
so_file=$(find /tmp/profdir/ -iname '*.so' -printf "%T+\t%p\n" | sort -r | head -n1 | awk '{print $2}')
google-pprof --text $so_file eigen-prof.log
This gives me
# Using local file /tmp/profdir/sourceCpp-x86_64-pc-linux-gnu-0.12.7/sourcecpp_5dc5531d6f20/sourceCpp_4.so.
# Using local file eigen-prof.log.
# Total: 2 samples
# 1 50.0% 50.0% 1 50.0% dsterf_
# 1 50.0% 100.0% 1 50.0% dsymv_
# 0 0.0% 100.0% 2 100.0% 0x00000000004007ca
# 0 0.0% 100.0% 2 100.0% 0x00000000004007fa
# 0 0.0% 100.0% 2 100.0% R_ReplConsole
# 0 0.0% 100.0% 2 100.0% Rf_ReplIteration
# 0 0.0% 100.0% 2 100.0% Rf_applyClosure
# 0 0.0% 100.0% 2 100.0% Rf_eval
# 0 0.0% 100.0% 2 100.0% __libc_start_main
# 0 0.0% 100.0% 2 100.0% arma::auxlib::eig_sym
# 0 0.0% 100.0% 1 50.0% dlatrd_
# 0 0.0% 100.0% 2 100.0% do_dotcall
# 0 0.0% 100.0% 2 100.0% dsyev_
# 0 0.0% 100.0% 1 50.0% dsytrd_
# 0 0.0% 100.0% 2 100.0% eig_sym (inline)
# 0 0.0% 100.0% 2 100.0% getEigenValues
# 0 0.0% 100.0% 2 100.0% run_Rmainloop
# 0 0.0% 100.0% 2 100.0% sourceCpp_1_getEigenValues
# 0 0.0% 100.0% 2 100.0% syev (inline)
I threw the second step together on the fly so don't judge me on that; but it's just searching the directory you passed to cacheDir
(/tmp/profdir
in my case) for the most recently created (modified) .so
file. You could also just grab the file name manually using Finder, etc. if your machine is lacking any of those programs.