I am trying to debug Rcpp compiled code at run-time. I have been trying to get this to work unsuccessfully, for a very long time.
A very similar question was asked here: Debugging (line by line) of Rcpp-generated DLL under Windows which asks the same question, but both the question and the answer are far beyond my understanding.
Here is what I have:
Windows 7 Pro SP1
R 3.5
Rstudio 1.1.463 with Rcpp.
Rbuild Tools from Rstudio. (c++ compiler)
Procedure:
In Rstudio File->New File->C++ File (creates a sample file with a timesTwo function.)
I added a new function in this file:
// [[Rcpp::export]]
NumericVector timesTwo2(NumericVector x) {
for(int ii = 0; ii <= x.size(); ii++)
{
x.at(ii) = x.at(ii) * 2;
}
return x;
}
I checked Source on Save and saved the file as RcppTest.cpp which sources or complies the file successfully.
Run code in Rstudio:
data = c(1:10)
data
[1] 1 2 3 4 5 6 7 8 9 10
timesTwo2(data)
Error in timesTwo2(data) : Index out of bounds: [index=10; extent=10].
The error is because in the for loop is <= x.size() so the result is a run-time error.
The question is how can get a debug output about this error that reasonably tells me what happened?
At the very least I would like to know the line in the code that triggered the exception and with which parameters.
Furthermore, I would really like to execute the code line-by-line to just before the exception so I can monitor exactly what is happening.
I can install any additional programs or apply any other settings as long as I can find precise details on how to do it. For now I am starting from scratch just to get it working. Thank you.
Update:
I found this site: Debugging Rcpp c++ code using gdb
I installed the latest gcc 8.1 with gdb
I found the CXXFLAGS in the makeconf file located in C:\Program Files\R\R-3.5.1\etc\x64
Then I started the Rgui as suggested, but when I try Rcpp:::sourceCpp I get an error:
> library(Rcpp)
> Rcpp::sourceCpp('Rcpptest.cpp')
C:/PROGRA~1/R/R-35~1.1/etc/x64/Makeconf:230: warning: overriding recipe for target '.m.o'
C:/PROGRA~1/R/R-35~1.1/etc/x64/Makeconf:223: warning: ignoring old recipe for target '.m.o'
c:/Rtools/mingw_64/bin/g++ -I"C:/PROGRA~1/R/R-35~1.1/include" -DNDEBUG -I"C:/Users/Michael/Documents/R/win-library/3.5/Rcpp/include" -I"C:/PROGRA~1/R/R-35~1.1/bin/x64" -ggdb -O0 -Wall -gdwarf-2 -mtune=generic -c Rcpptest.cpp -o Rcpptest.o
process_begin: CreateProcess(NULL, c:/Rtools/mingw_64/bin/g++ -IC:/PROGRA~1/R/R-35~1.1/include -DNDEBUG -IC:/Users/Michael/Documents/R/win-library/3.5/Rcpp/include -IC:/PROGRA~1/R/R-35~1.1/bin/x64 -ggdb -O0 -Wall -gdwarf-2 -mtune=generic -c Rcpptest.cpp -o Rcpptest.o, ...) failed.
make (e=2): The system cannot find the file specified.
make: *** [C:/PROGRA~1/R/R-35~1.1/etc/x64/Makeconf:215: Rcpptest.o] Error 2
Error in Rcpp::sourceCpp("Rcpptest.cpp") :
Error 1 occurred building shared library.
WARNING: The tools required to build C++ code for R were not found.
Please download and install the appropriate version of Rtools:
http://cran.r-project.org/bin/windows/Rtools/
It looks like it is loading the new CXXFLAGS and it is using DEBUG, but it seems that it still cannot compile. Anybody know why from the error?
I tried running Rstudio the same way as Rgui and it started with many threads showing in the gdb window, but everything in Rstudio ran exactly as before with no additional debug information from Rstudio or gdb.
Update 2:
As the error above states that Rgui did not have Rtools for compiling so I installed the Rtools from the provide link. It installed in C:\Rtools while Rstudio installed in C:\RBuildTools. So I now have 3 compilers, Rtools, RbuildTools and gcc with gdb.
It compiles now, but still gives the same error as I did in Rstudio. I would like to at least get better error output, like the line and value passed.
The instruction say Rgui should have a spot for a break-point, but I cannot find such an option.
Update 3
I was finally able to set up and run a Linux install (Ubuntu 16.04.05).
First here are my CXXFLAGS:
$ R CMD config CXXFLAGS
-g -O0 -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 -g
I had to create a .R folder in my home directory and a Makevar file in it with just the line
CXXFLAGS = -g -O0 -Wall -pedantic -fstack-protector-strong -D_FORTIFY_SOURCE=2
This alone took hours as nowhere did it actually say make the folder and file.
Then I executed the commands as Ralf posted, at the break point:
> timesTwo2(d1)
Thread 1 "R" hit Breakpoint 1, timesTwo2 (x=...) at RcppTest.cpp:19
19 NumericVector timesTwo2(NumericVector x) {
(gdb) n
20 for (int ii = 0; ii <= x.size(); ii++)
(gdb) n
22 x.at(ii) = x.at(ii) * 2;
(gdb) display ii
1: ii = 0
(gdb) n
20 for (int ii = 0; ii <= x.size(); ii++)
1: ii = 0
(gdb) n
22 x.at(ii) = x.at(ii) * 2;
1: ii = 1
(gdb) n
20 for (int ii = 0; ii <= x.size(); ii++)
1: ii = 1
(gdb) display x.at(ii)
2: x.at(ii) = <error: Attempt to take address of value not located in memory.>
(gdb) n
22 x.at(ii) = x.at(ii) * 2;
1: ii = 2
2: x.at(ii) = <error: Attempt to take address of value not located in memory.>
(gdb)
And finally at n = 10:
1: ii = 10
2: x.at(ii) = <error: Attempt to take address of value not located in memory.>
(gdb) n
0x00007ffff792d762 in Rf_applyClosure () from /usr/lib/R/lib/libR.so
(gdb)
This is definitely the furthest I have come to debugging, but this is a very basic function and the debug output and even the error output was not very useful. It gave me the line it was executing and it could display ii, but I could not display the array value or the entire array. Is it possible to create a more specific break point such that it only breaks when ii == 10?
Ideally I would like this in Rstudio or some other GUI that can display the entire vector. Still doing more testing.
The usual approach R -d gdb, which I also suggested in my original answer below, does not work on Windows:
--debugger=name
-d name
(UNIX only) Run R through debugger name. For most debuggers (the exceptions are valgrind and recent versions of gdb), further command line options are disregarded, and should instead be given when starting the R executable from inside the debugger.
https://cran.r-project.org/doc/manuals/r-release/R-intro.html#Invoking-R-from-the-command-line
Alternative:
Start R in debugger: gdb.exe Rgui.exe
Set break point: break TimesTwo2
Run R: run
Source file: Rcpp::sourceCpp("debug.cpp")
Use next, print, display to step through the code.
An alternative to step 1. would be to start R, get the PID with Sys.getpid(), attach debugger with gdb -p <pid>. You will than have to use continue instead of run.
I don't have a Windows machine right now, so the following was done on Linux. I hope it is transferable, though. Let's start with a simple cpp file (debug.cpp in my case) that contains your code:
#include <Rcpp.h>
using Rcpp::NumericVector;
// [[Rcpp::export]]
NumericVector timesTwo2(NumericVector x) {
for(int ii = 0; ii <= x.size(); ii++)
{
x.at(ii) = x.at(ii) * 2;
}
return x;
}
/*** R
data = c(1:10)
data
timesTwo2(data)
*/
I can reproduce the error by calling R on the command line:
$ R -e "Rcpp::sourceCpp('debug.cpp')"
R version 3.5.1 (2018-07-02) -- "Feather Spray"
[...]
> Rcpp::sourceCpp('debug.cpp')
> data = c(1:10)
> data
[1] 1 2 3 4 5 6 7 8 9 10
> timesTwo2(data)
Error in timesTwo2(data) : Index out of bounds: [index=10; extent=10].
Calls: <Anonymous> ... source -> withVisible -> eval -> eval -> timesTwo2 -> .Call
Execution halted
Next we can start R with gdb as debugger (c.f. Writing R Extensions as Dirk said):
$ R -d gdb -e "Rcpp::sourceCpp('debug.cpp')"
GNU gdb (Debian 8.2-1) 8.2
[...]
(gdb) break timesTwo2
Function "timesTwo2" not defined.
Make breakpoint pending on future shared library load? (y or [n]) y
Breakpoint 1 (timesTwo2) pending.
(gdb) run
[...]
> Rcpp::sourceCpp('debug.cpp')
[Thread 0xb40d3b40 (LWP 31793) exited]
[Detaching after fork from child process 31795]
> data = c(1:10)
> data
[1] 1 2 3 4 5 6 7 8 9 10
> timesTwo2(data)
Thread 1 "R" hit Breakpoint 1, 0xb34f3310 in timesTwo2(Rcpp::Vector<14, Rcpp::PreserveStorage>)#plt ()
from /tmp/RtmphgrjLg/sourceCpp-i686-pc-linux-gnu-1.0.0/sourcecpp_7c2d7f56744b/sourceCpp_2.so
(gdb)
At this point you can single step through the program using next (or just n) and output variables using print (or just p). A useful command is also display:
Thread 1 "R" hit Breakpoint 1, timesTwo2 (x=...) at debug.cpp:5
5 NumericVector timesTwo2(NumericVector x) {
(gdb) n
6 for(int ii = 0; ii <= x.size(); ii++)
(gdb) n
8 x.at(ii) = x.at(ii) * 2;
(gdb) display ii
2: ii = 0
(gdb) n
8 x.at(ii) = x.at(ii) * 2;
2: ii = 0
[...]
2: ii = 9
(gdb)
46 inline proxy ref(R_xlen_t i) { return start[i] ; }
2: ii = 9
(gdb)
6 for(int ii = 0; ii <= x.size(); ii++)
2: ii = 10
(gdb)
8 x.at(ii) = x.at(ii) * 2;
2: ii = 10
(gdb)
Error in timesTwo2(data) : Index out of bounds: [index=10; extent=10].
Calls: <Anonymous> ... source -> withVisible -> eval -> eval -> timesTwo2 -> .Call
Execution halted
[Detaching after fork from child process 32698]
[Inferior 1 (process 32654) exited with code 01]
BTW, I used the following compile flags:
$ R CMD config CXXFLAGS
-g -O2 -Wall -pedantic -fstack-protector-strong -D_FORTIFY_SOURCE=2
You might want to switch to -O0.
It can be done with Visual Studio Code, since it can handle both R and C++. This allows you to step through your Rcpp code one line at a time in a GUI environment.
See this demo to get started.
Related
I am new to Frama-C. I specifically need to use e-acsl plugin for verification purposes. I used first.i file as
int main(void) {
int x = 0;
/∗# assert x == 0; ∗/
/∗# assert x == 1; ∗/
return 0;
}
Created monitored_first.c file from first.i file using the following command.
$ frama-c -e-acsl first.i -then-last -print -ocode monitored_first.c
The main function inside the monitored_first.c looks like the one below.
int main(void)
{
int __retres;
__e_acsl_memory_init((int *)0,(char ***)0,8UL);
int x = 0;
__retres = 0;
__e_acsl_memory_clean();
return __retres;
}
It is not adding e_acsl assertion for x==1.
I tried it using the "e-acsl-gcc.sh" script , which generated the monitored_first.i file. But the main function inside monitored_first.i is same as that in monitored_first.c.
$ e-acsl-gcc.sh -c -omonitored_first.i first.i
The above command generated two executable, "a.out.e-acsl" and "a.out". It also generates some warnings when run in ubuntu 22.04 as follows:
/home/amrutha/.opam/4.11.1/bin/frama-c -remove-unused-specified-functions -machdep gcc_x86_64 '-cpp-extra-args= -std=c99 -D_DEFAULT_SOURCE -D__NO_CTYPE -D__FC_MACHDEP_X86_64 ' -no-frama-c-stdlib first.i -e-acsl -e-acsl-share=/home/amrutha/.opam/4.11.1/bin/../share/frama-c/e-acsl -then-last -print -ocode monitored_first.i
[kernel] Parsing first.i (no preprocessing)
[e-acsl] beginning translation.
[kernel] Parsing FRAMAC_SHARE/e-acsl/e_acsl.h (with preprocessing)
/tmp/ppannot15ad34.c:362: warning: "__STDC_IEC_60559_BFP__" redefined
362 | #define __STDC_IEC_60559_BFP__ 201404L
|
In file included from <command-line>:
/usr/include/stdc-predef.h:39: note: this is the location of the previous definition
39 | # define __STDC_IEC_60559_BFP__ 201404L
|
/tmp/ppannot15ad34.c:363: warning: "__STDC_IEC_60559_COMPLEX__" redefined
363 | #define __STDC_IEC_60559_COMPLEX__ 201404L
|
In file included from <command-line>:
/usr/include/stdc-predef.h:49: note: this is the location of the previous definition
49 | # define __STDC_IEC_60559_COMPLEX__ 201404L
|
[e-acsl] translation done in project "e-acsl".
+ gcc -std=c99 -m64 -g -O2 -fno-builtin -fno-merge-constants -Wall -Wno-long-long -Wno-attributes -Wno-nonnull -Wno-undef -Wno-unused -Wno-unused-function -Wno-unused-result -Wno-unused-value -Wno-unused-function -Wno-unused-variable -Wno-unused-but-set-variable -Wno-implicit-function-declaration -Wno-empty-body first.i -o a.out
+ gcc -DE_ACSL_SEGMENT_MMODEL -std=c99 -m64 -g -O2 -fno-builtin -fno-merge-constants -Wall -Wno-long-long -Wno-attributes -Wno-nonnull -Wno-undef -Wno-unused -Wno-unused-function -Wno-unused-result -Wno-unused-value -Wno-unused-function -Wno-unused-variable -Wno-unused-but-set-variable -Wno-implicit-function-declaration -Wno-empty-body -I/home/amrutha/.opam/4.11.1/bin/../share/frama-c/e-acsl -o a.out.e-acsl monitored_first.i /home/amrutha/.opam/4.11.1/bin/../share/frama-c/e-acsl/e_acsl_rtl.c /home/amrutha/.opam/4.11.1/bin/../lib/frama-c/e-acsl/libeacsl-dlmalloc.a -lgmp -lm
In ubuntu 20.04 there is no any warning, only the end part is getting displayed. When run ./a.out.e-acsl , it simply run the code without any message, which is not supposed. The expected output should look like this:
$ ./a.out.e-acsl
first.i: In function 'main'
first.i:4: Error: Assertion failed:
The failing predicate is:
x == 1.
Aborted (core dumped)
$ echo $?
134
I tried it in ubuntu 22.04 with opam version 2.1.2 and Fragma-C 25.0
and ubuntu 20.04 with opam version 2.0.5 and Fragma-C 25.0
The same issue has been posted to Frama-C's public bug tracking and it seems the cause might have been the non-ASCII asterisk characters used in the ACSL annotations: ∗ instead of *.
I still don't understand how the comments could parse at all (my compiler gives a syntax error), but the user seems to indicate that replacing them solved the problem.
In any case, in similar situations one can either use the Frama-C GUI to open the parsed file and check if Frama-C recognizes the ACSL annotations (they should show up in the CIL normalized code), or try other analyses, e.g. running frama-c -eva and checking that it detects the annotations.
I am trying to run a very simple model with rstan in batch mode and have some errors. I do not have any errors when I try to run the same code not in batch mode.
The community from STAN Forums helped me to understand that the issue is that Rcpp instead of STAN is not working properly on the server of my university. We reached this understanding from a test trying to run a very simple Rcpp code in batch mode and not in batch mode. The Rcpp code is:
### Libraries
library(Rcpp)
Rcpp::sourceCpp(code='
#include <Rcpp.h>
// [[Rcpp::export]]
int fibonacci(const int x) {
if (x == 0) return(0);
if (x == 1) return(1);
return (fibonacci(x - 1)) + fibonacci(x - 2);
}',
verbose = TRUE,
rebuild = TRUE
)
The results are below.
Not in batch mode:
Generated R functions
-------------------------------------------------------
`.sourceCpp_1_DLLInfo` <- dyn.load('/tmp/RtmpDNL6of/sourceCpp-x86_64-pc-linux-gnu-1.0.7/sourcecpp_178b21d435d91/sourceCpp_4.so')
fibonacci <- Rcpp:::sourceCppFunction(function(x) {}, FALSE, `.sourceCpp_1_DLLInfo`, 'sourceCpp_1_fibonacci')
rm(`.sourceCpp_1_DLLInfo`)
Building shared library
--------------------------------------------------------
DIR: /tmp/RtmpDNL6of/sourceCpp-x86_64-pc-linux-gnu-1.0.7/sourcecpp_178b21d435d91
/hpc/apps/R/4.1.2/lib64/R/bin/R CMD SHLIB --preclean -o 'sourceCpp_4.so' 'file178b25628f5ea.cpp'
g++ -std=gnu++14 -I"/hpc/apps/R/4.1.2/lib64/R/include" -DNDEBUG -I"/hpc/home/user/R/x86_64-pc-linux-gnu-library/4.1/Rcpp/include" -I"/tmp/RtmpDNL6of/sourceCpp-x86_64-pc-linux-gnu-1.0.7" -I/hpc/apps/zlib/1.2.8/include -I/hpc/apps/pcre/8.38/include -I/hpc/apps/bzip2/1.0.6/include -I/hpc/apps/curl/7.54.1/include -I/hpc/apps/cairo/1.14.12/include -fpic -g -O2 -c file178b25628f5ea.cpp -o file178b25628f5ea.o
g++ -std=gnu++14 -shared -L/hpc/apps/R/4.1.2/lib64/R/lib -L/hpc/apps/zlib/1.2.8/lib -L/hpc/apps/pcre/8.38/lib -L/hpc/apps/bzip2/1.0.6/lib -L/hpc/apps/curl/7.54.1/lib -L/hpc/apps/cairo/1.14.12/lib -o sourceCpp_4.so file178b25628f5ea.o -L/hpc/apps/R/4.1.2/lib64/R/lib -lR
In batch mode:
Generated R functions
-------------------------------------------------------
`.sourceCpp_1_DLLInfo` <- dyn.load('/localscratch/250948.1.ragatkolab.q/RtmpDlK5Sy/sourceCpp-x86_64-pc-linux-gnu-1.0.7/sourcecpp_142bd68d660f1/sourceCpp_2.so')
fibonacci <- Rcpp:::sourceCppFunction(function(x) {}, FALSE, `.sourceCpp_1_DLLInfo`, 'sourceCpp_1_fibonacci')
rm(`.sourceCpp_1_DLLInfo`)
Building shared library
--------------------------------------------------------
DIR: /localscratch/250948.1.mylab.q/RtmpDlK5Sy/sourceCpp-x86_64-pc-linux-gnu-1.0.7/sourcecpp_142bd68d660f1
/hpc/apps/R/4.1.2/lib64/R/bin/R CMD SHLIB -o 'sourceCpp_2.so' 'file142bd64ebe902.cpp'
g++ -std=gnu++14 -I"/hpc/apps/R/4.1.2/lib64/R/include" -DNDEBUG -I"/hpc/home/user/R/x86_64-pc-linux-gnu-library/4.1/Rcpp/include" -I"/localscratch/250948.1.ragatkolab.q/RtmpDlK5Sy/sourceCpp-x86_64-pc-linux-gnu-1.0.7" -I/hpc/apps/zlib/1.2.8/include -I/hpc/apps/pcre/8.38/include -I/hpc/apps/bzip2/1.0.6/include -I/hpc/apps/curl/7.54.1/include -I/hpc/apps/cairo/1.14.12/include -fpic -g -O2 -c file142bd64ebe902.cpp -o file142bd64ebe902.o
In file included from /hpc/apps/gcc/9.1.0/include/c++/9.1.0/x86_64-pc-linux-gnu/bits/c++config.h:524,
from /hpc/apps/gcc/9.1.0/include/c++/9.1.0/cmath:41,
from /hpc/home/user/R/x86_64-pc-linux-gnu-library/4.1/Rcpp/include/Rcpp/platform/compiler.h:100,
from /hpc/home/user/R/x86_64-pc-linux-gnu-library/4.1/Rcpp/include/Rcpp/r/headers.h:66,
from /hpc/home/user/R/x86_64-pc-linux-gnu-library/4.1/Rcpp/include/RcppCommon.h:30,
from /hpc/home/user/R/x86_64-pc-linux-gnu-library/4.1/Rcpp/include/Rcpp.h:27,
from file142bd64ebe902.cpp:2:
/hpc/apps/gcc/9.1.0/include/c++/9.1.0/x86_64-pc-linux-gnu/bits/os_defines.h:39:10: fatal error: features.h: No such file or directory
39 | #include <features.h>
| ^~~~~~~~~~~~
compilation terminated.
make: *** [file142bd64ebe902.o] Error 1
Error in Rcpp::sourceCpp(code = "\n #include <Rcpp.h>\n\n // [[Rcpp::export]]\n int fibonacci(const int x) {\n if (x == 0) return(0);\n if (x == 1) return(1);\n return (fibonacci(x - 1)) + fibonacci(x - 2);\n }", :
Error 1 occurred building shared library.
WARNING: The tools required to build C++ code for R were not found.
Please install GNU development tools including a C++ compiler.
Execution halted
Then, they asked me to modify my makevars file - which I did using the R-package usethis::edit_r_makevars() - adding the lines:
CXXFLAGS += -I"/hpc/apps/gcc/9.1.0/include/c++/9.1.0/parallel/"
CXX14FLAGS += -I"/hpc/apps/gcc/9.1.0/include/c++/9.1.0/parallel/"
Once I did this modification (I hope I did it correctly), my error message change to:
Generated extern "C" functions
--------------------------------------------------------
#include <Rcpp.h>
#ifdef RCPP_USE_GLOBAL_ROSTREAM
Rcpp::Rostream<true>& Rcpp::Rcout = Rcpp::Rcpp_cout_get();
Rcpp::Rostream<false>& Rcpp::Rcerr = Rcpp::Rcpp_cerr_get();
#endif
// fibonacci
int fibonacci(const int x);
RcppExport SEXP sourceCpp_1_fibonacci(SEXP xSEXP) {
BEGIN_RCPP
Rcpp::RObject rcpp_result_gen;
Rcpp::RNGScope rcpp_rngScope_gen;
Rcpp::traits::input_parameter< const int >::type x(xSEXP);
rcpp_result_gen = Rcpp::wrap(fibonacci(x));
return rcpp_result_gen;
END_RCPP
}
Generated R functions
-------------------------------------------------------
`.sourceCpp_1_DLLInfo` <- dyn.load('/localscratch/251578.1.mylablab.q/RtmpCHyEAd/sourceCpp-x86_64-pc-linux-gnu-1.0.7/sourcecpp_1e50364a03315/sourceCpp_2.so')
fibonacci <- Rcpp:::sourceCppFunction(function(x) {}, FALSE, `.sourceCpp_1_DLLInfo`, 'sourceCpp_1_fibonacci')
rm(`.sourceCpp_1_DLLInfo`)
Building shared library
--------------------------------------------------------
DIR: /localscratch/251578.1.mylablab.q/RtmpCHyEAd/sourceCpp-x86_64-pc-linux-gnu-1.0.7/sourcecpp_1e50364a03315
/hpc/apps/R/4.1.2/lib64/R/bin/R CMD SHLIB -o 'sourceCpp_2.so' 'file1e50325e7686.cpp'
g++ -std=gnu++14 -I"/hpc/apps/R/4.1.2/lib64/R/include" -DNDEBUG -I"/hpc/home/user/R/x86_64-pc-linux-gnu-library/4.1/Rcpp/include" -I"/localscratch/251578.1.mylablab.q/RtmpCHyEAd/sourceCpp-x86_64-pc-linux-gnu-1.0.7" -I/hpc/apps/zlib/1.2.8/include -I/hpc/apps/pcre/8.38/include -I/hpc/apps/bzip2/1.0.6/include -I/hpc/apps/curl/7.54.1/include -I/hpc/apps/cairo/1.14.12/include -fpic -g -O2 -I"/hpc/apps/gcc/9.1.0/include/c++/9.1.0/parallel/" -c file1e50325e7686.cpp -o file1e50325e7686.o
In file included from /hpc/apps/gcc/11.1.0/include/c++/11.1.0/x86_64-pc-linux-gnu/bits/c++config.h:571,
from /hpc/apps/gcc/11.1.0/include/c++/11.1.0/cmath:41,
from /hpc/home/user/R/x86_64-pc-linux-gnu-library/4.1/Rcpp/include/Rcpp/platform/compiler.h:100,
from /hpc/home/user/R/x86_64-pc-linux-gnu-library/4.1/Rcpp/include/Rcpp/r/headers.h:66,
from /hpc/home/user/R/x86_64-pc-linux-gnu-library/4.1/Rcpp/include/RcppCommon.h:30,
from /hpc/home/user/R/x86_64-pc-linux-gnu-library/4.1/Rcpp/include/Rcpp.h:27,
from file1e50325e7686.cpp:2:
/hpc/apps/gcc/11.1.0/include/c++/11.1.0/x86_64-pc-linux-gnu/bits/os_defines.h:44:19: error: missing binary operator before token "("
44 | #if __GLIBC_PREREQ(2,15) && defined(_GNU_SOURCE)
| ^
/hpc/apps/gcc/11.1.0/include/c++/11.1.0/x86_64-pc-linux-gnu/bits/os_defines.h:52:19: error: missing binary operator before token "("
52 | #if __GLIBC_PREREQ(2, 27)
| ^
In file included from /hpc/home/user/R/x86_64-pc-linux-gnu-library/4.1/Rcpp/include/Rcpp/platform/compiler.h:100,
from /hpc/home/user/R/x86_64-pc-linux-gnu-library/4.1/Rcpp/include/Rcpp/r/headers.h:66,
from /hpc/home/user/R/x86_64-pc-linux-gnu-library/4.1/Rcpp/include/RcppCommon.h:30,
from /hpc/home/user/R/x86_64-pc-linux-gnu-library/4.1/Rcpp/include/Rcpp.h:27,
from file1e50325e7686.cpp:2:
/hpc/apps/gcc/11.1.0/include/c++/11.1.0/cmath:45:15: fatal error: math.h: No such file or directory
45 | #include_next <math.h>
| ^~~~~~~~
compilation terminated.
make: *** [file1e50325e7686.o] Error 1
Error in Rcpp::sourceCpp(code = "\n #include <Rcpp.h>\n\n // [[Rcpp::export]]\n int fibonacci(const int x) {\n if (x == 0) return(0);\n if (x == 1) return(1);\n return (fibonacci(x - 1)) + fibonacci(x - 2);\n }", :
Error 1 occurred building shared library.
WARNING: The tools required to build C++ code for R were not found.
Please install GNU development tools including a C++ compiler.
Execution halted
My knowledge in Linux is limited and I am afraid that my question is out of scope for STAN Forums. Any thoughts how to proceed?
I fear your problem is still local. On the computing you use, someone may have set up R in way that makes it differ between interactive R use, and what you call batch use.
But that is non-standard, and at your end. In general, it just works. Using a minimally modified version of your program (which I still find confusing: it loads doParallel, registers cores but ... triggers to parallel code -- anyway) it works just fine:
Using Rscript
edd#rob:~/git/stackoverflow/70470842(master)$ Rscript answer.R
Loading required package: foreach
Loading required package: iterators
Loading required package: parallel
Fib(10) is 55
edd#rob:~/git/stackoverflow/70470842(master)$
Using R in batch mode
edd#rob:~/git/stackoverflow/70470842(master)$ R -s -f answer.R
Loading required package: foreach
Loading required package: iterators
Loading required package: parallel
Fib(10) is 55
edd#rob:~/git/stackoverflow/70470842(master)$
Using our littler frontend
edd#rob:~/git/stackoverflow/70470842(master)$ r answer.R
Loading required package: foreach
Loading required package: iterators
Loading required package: utils
Loading required package: parallel
Fib(10) is 55
edd#rob:~/git/stackoverflow/70470842(master)$
Modified source code
library(doParallel) # Library
ncores <- 5 # Simulation parameters
n_sim <- 5
registerDoParallel(ncores)
Rcpp::sourceCpp(code='
#include <Rcpp.h>
// [[Rcpp::export]]
int fibonacci(const int x) {
if (x == 0) return(0);
if (x == 1) return(1);
return (fibonacci(x - 1)) + fibonacci(x - 2);
}'
)
cat("Fib(10) is ", fibonacci(10), "\n")
For future reference, I interacted with IT team from my institution after feedback received here and STAN Forums, and they finally found a solution. In their words:
"Compute nodes aren't normally used for development. So certain development packages are not installed by default. We installed "glibc-devel" and "glibc-headers" on the compute nodes.
So, it seems that when run interactively the job was running on the submit node (which had these libraries installed) and when run from the scheduler it was run on the compute nodes (which did not have the library installed). The reason for the discrepancy being that the libraries in question have traditionally been only used during development and compilation. This use posed a unique use case."
1. how to create loadable kernel module on solaris 11?
simple loadable kernel module (hello world).
I searched, but only showed how to create a Linux kernel module.
in linux, header linux/kernel.h, but not included header on solaris
2. how to compile loadable kernel module on solaris 11?
gcc -D_KERNEL -m64 -c cpluscplus.cpp
Is it appropriate to compile as above?
64bit, x86
Here's the minimal hello world kernel module I can come up with:
#include <sys/modctl.h>
#include <sys/cmn_err.h>
/*
* Module linkage information for the kernel.
*/
static struct modlmisc modlmisc = {
&mod_miscops, "test module"
};
static struct modlinkage modlinkage = {
MODREV_1, (void *)&modlmisc, NULL
};
int
_init(void)
{
return (mod_install(&modlinkage));
}
int
_fini(void)
{
return (mod_remove(&modlinkage));
}
int
_info(struct modinfo *modinfop)
{
cmn_err(CE_NOTE, "hello kernel");
return (mod_info(&modlinkage, modinfop));
}
Compiling this as 64-bit binary with Oracle Developer Studio 12.6 and the Solaris linker like so:
cc -D_KERNEL -I include -m64 -c foomod.c
ld -64 -z type=kmod -znodefs -o foomod foomod.o
For GCC you will likely need a distinct set of options.
Then load it with:
modload ./foomod
This will complain about signature verification. This is innocuous unless you are running the system with Verified Boot enabled.
Check that module is loaded:
# modinfo -i foomod
ID LOADADDR SIZE INFO REV NAMEDESC
312 fffffffff7a8ddc0 268 -- 1 foomod (test module)
# dmesg | tail -1
Mar 16 12:22:57 ST091 foomod: [ID 548715 kern.notice] NOTICE: hello kernel
This works on Solaris 11.4 SRU 33 running on x86 machine (VirtualBox instance in fact).
I was trying to run this peace of code in R (credit to the author):
require(Rcpp)
require(RcppArmadillo)
require(inline)
cosineRcpp <- cxxfunction(
signature(Xs = "matrix"),
plugin = c("RcppArmadillo"),
body='
Rcpp::NumericMatrix Xr(Xs); // creates Rcpp matrix from SEXP
int n = Xr.nrow(), k = Xr.ncol();
arma::mat X(Xr.begin(), n, k, false); // reuses memory and avoids extra copy
arma::mat Y = arma::trans(X) * X; // matrix product
arma::mat res = (1 - Y / (arma::sqrt(arma::diagvec(Y)) * arma::trans(arma::sqrt(arma::diagvec(Y)))));
return Rcpp::wrap(res);
')
And got, after few fixes, the following error:
Error in compileCode(f, code, language = language, verbose = verbose) :
Compilation ERROR, function(s)/method(s) not created!
clang: error: no such file or directory: '/usr/local/lib/libfontconfig.a'
clang: error: no such file or directory: '/usr/local/lib/libreadline.a'
make: *** [file5a681e35ebe1.so] Error 1
In addition: Warning message:
running command '/Library/Frameworks/R.framework/Resources/bin/R CMD SHLIB file5a681e35ebe1.cpp 2> file5a681e35ebe1.cpp.err.txt' had status 1
I used to use Rcpp a lot in the past. But between now and then my computer has been reformatted and all the installation re-done using homebrew.
I installed cairo with brew: brew install cairo
the libreadline.a error was solved with:
brew link --force readline
But the same did not work for libfontconfig.a since was already linked:
brew link --force fontconfig
Warning: Already linked: /usr/local/Cellar/fontconfig/2.11.1
To relink: brew unlink fontconfig && brew link fontconfig
I would have assumed that fontconfig is within cairo. In fact, when I type
brew install fontconfig
Warning: fontconfig-2.11.1 already installed
But the truth is that there is no libfontconfig.a at /usr/local/lib/:
ls /usr/local/lib/libfont*
/usr/local/lib/libfontconfig.1.dylib
/usr/local/lib/libfontconfig.dylib
Using the very questionable approach of going here and download it, the code runs, but still gives a the corresponding warning, since the file corresponds to a different os.x architecture (I did not found one for 10.9):
+ . + ld: warning: ignoring file /usr/local/lib/libfontconfig.a, missing required architecture x86_64 in file /usr/local/lib/libfontconfig.a (2 slices)
So at this stage I am a little lost.
How do I install libfontconfig.a or find the 10.9 version?
In case is of any use, I have Xcode installed, I am on a Mac 10.9.5,
and based on this very nice and detailed answer my ~/.R/Makevars file looks like:
CC=clang
CXX=clang++
FLIBS=-L/usr/local/bin/
Your system setup is broken. Neither R nor Rcpp have anything to do with clang (unless you chose clang as your system compiler) or fontconfig.
So start simpler:
R> library(Rcpp)
R> evalCpp("2 + 2")
[1] 4
R>
This just showed that my system has a working compiler R (and Rcpp) can talk to. We can it more explicit:
R> evalCpp("2 + 2", verbose=TRUE)
Generated code for function definition:
--------------------------------------------------------
#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]
SEXP get_value(){ return wrap( 2 + 2 ) ; }
No rebuild required (use rebuild = TRUE to force a rebuild)
[1] 4
R>
and R is clever enough not to rebuild. We can then force a build
R> evalCpp("2 + 2", verbose=TRUE, rebuild=TRUE)
Generated code for function definition:
--------------------------------------------------------
#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]
SEXP get_value(){ return wrap( 2 + 2 ) ; }
Generated extern "C" functions
--------------------------------------------------------
#include <Rcpp.h>
// get_value
SEXP get_value();
RcppExport SEXP sourceCpp_0_get_value() {
BEGIN_RCPP
Rcpp::RObject __result;
Rcpp::RNGScope __rngScope;
__result = Rcpp::wrap(get_value());
return __result;
END_RCPP
}
Generated R functions
-------------------------------------------------------
`.sourceCpp_0_DLLInfo` <- dyn.load('/tmp/Rtmpeuaiu4/sourcecpp_6a7c7c8295fc/sourceCpp_2.so')
get_value <- Rcpp:::sourceCppFunction(function() {}, FALSE, `.sourceCpp_0_DLLInfo`, 'sourceCpp_0_get_value')
rm(`.sourceCpp_0_DLLInfo`)
Building shared library
--------------------------------------------------------
DIR: /tmp/Rtmpeuaiu4/sourcecpp_6a7c7c8295fc
/usr/lib/R/bin/R CMD SHLIB -o 'sourceCpp_2.so' --preclean 'file6a7c6d1fc2d6.cpp'
ccache g++ -I/usr/share/R/include -DNDEBUG -I"/usr/local/lib/R/site-library/Rcpp/include" -I"/tmp/Rtmpeuaiu4" -fpic -g -O3 -Wall -pipe -Wno-unused -pedantic -c file6a7c6d1fc2d6.cpp -o file6a7c6d1fc2d6.o
g++ -shared -L/usr/lib/R/lib -Wl,-Bsymbolic-functions -Wl,-z,relro -o sourceCpp_2.so file6a7c6d1fc2d6.o -L/usr/lib/R/lib -lR
[1] 4
R>
and on that you see system details on my side (Linux, also using ccache) that will be different for you.
After that, try (Rcpp)Armadillo one-liners and so on.
I have a newb problem with compiling and linking the kissfft library 'out of the box'. I've downloaded the kissfft library and extracted it to a test directory. Upon entering the directory and running 'make testall' I get the following errors, which look like the std c math library is not being linked to properly.
sharkllama#quaaludes:~/KISSFFT/kiss_fft129$ make testall
# The simd and int32_t types may or may not work on your machine
make -C test DATATYPE=simd CFLAGADD="" test
make[1]: Entering directory `/home/sharkllama/KISSFFT/kiss_fft129/test'
cd ../tools && make all
make[2]: Entering directory `/home/sharkllama/KISSFFT/kiss_fft129/tools'
cc -o fft_simd -Wall -O3 -W -Wall -Wstrict-prototypes -Wmissing-prototypes -Waggregate-return -Wcast-align -Wcast-qual -Wnested-externs -Wshadow -Wbad-function-cast -Wwrite-strings -I.. -DUSE_SIMD=1 -msse -lm ../kiss_fft.c fftutil.c kiss_fftnd.c kiss_fftr.c kiss_fftndr.c
/tmp/ccFbS0yK.o: In function `kiss_fft_alloc':
kiss_fft.c:(.text+0xd17): undefined reference to `sincos'
kiss_fft.c:(.text+0xd6b): undefined reference to `floor'
kiss_fft.c:(.text+0xe07): undefined reference to `sincos'
kiss_fft.c:(.text+0xeba): undefined reference to `sqrt'
/tmp/ccbYqDcf.o: In function `kiss_fftr_alloc':
kiss_fftr.c:(.text+0x118): undefined reference to `sincos'
kiss_fftr.c:(.text+0x188): undefined reference to `sincos'
collect2: ld returned 1 exit status
make[2]: *** [fft_simd] Error 1
make[2]: Leaving directory `/home/sharkllama/KISSFFT/kiss_fft129/tools'
make[1]: *** [tools] Error 2
make[1]: Leaving directory `/home/sharkllama/KISSFFT/kiss_fft129/test'
make: *** [testall] Error 2
sharkllama#quaaludes:~/KISSFFT/kiss_fft129$
Clearly, the makefile is trying to link to the math library as the -lm option has been included. Can't make any sense of this. I've compiled numerous programs that properly link to the math library before. Any help would be appreciated.
Thanks,
-B
Kissfft is not really something you need to make and install like other libraries. If you need complex ffts, then all you need to do is compile the kiss_fft.c in your project. If you need something more specialized like multidimensional or real ffts, then you should also compile the apropriate file(s) from the tools dir.
The make targets are largely for development testing of kissfft. There are a lot of system requirements to do that testing. Unless you are changing the internals of kissfft, you won't need to use those testing targets.
Just wanted to share a practical example on how to build a simple application using 1D FFT/IFFT from kissfft:
g++ example.cpp -o example -I kissfft kissfft/kiss_fft.c
example.cpp:
#include "kissfft/kiss_fft.h"
int main()
{
// initialize input data for FFT
float input[] = { 11.0f, 3.0f, 4.05f, 9.0f, 10.3f, 8.0f, 4.934f, 5.11f };
int nfft = sizeof(input) / sizeof(float); // nfft = 8
// allocate input/output 1D arrays
kiss_fft_cpx* cin = new kiss_fft_cpx[nfft];
kiss_fft_cpx* cout = new kiss_fft_cpx[nfft];
// initialize data storage
memset(cin, 0, nfft * sizeof(kiss_fft_cpx));
memset(cout, 0, nfft * sizeof(kiss_fft_cpx));
// copy the input array to cin
for (int i = 0; i < nfft; ++i)
{
cin[i].r = input[i];
}
// setup the size and type of FFT: forward
bool is_inverse_fft = false;
kiss_fft_cfg cfg_f = kiss_fft_alloc(nfft, is_inverse_fft, 0, 0); // typedef: struct kiss_fft_state*
// execute transform for 1D
kiss_fft(cfg_f, cin , cout);
// transformed: DC is stored in cout[0].r and cout[0].i
printf("\nForward Transform:\n");
for (int i = 0; i < nfft; ++i)
{
printf("#%d %f %fj\n", i, cout[i].r, cout[i].i);
}
// setup the size and type of FFT: backward
is_inverse_fft = true;
kiss_fft_cfg cfg_i = kiss_fft_alloc(nfft, is_inverse_fft, 0, 0);
// execute the inverse transform for 1D
kiss_fft(cfg_i, cout, cin);
// original input data
printf("\nInverse Transform:\n");
for (int i = 0; i < nfft; ++i)
{
printf("#%d %f\n", i, cin[i].r / nfft); // div by N to scale data back to the original range
}
// release resources
kiss_fft_free(cfg_f);
kiss_fft_free(cfg_i);
delete[] cin;
delete[] cout;
return 0;
}
To use the 2D transforms, include the appropriate header "kissfft/tools/kiss_fftnd.h" and adjust the build command to:
g++ example.cpp -o example -I kissfft kissfft/kiss_fft.c kissfft/tools/kiss_fftnd.c
Simple enough!