I am writing an R package in which one of the functions takes Rcpp::XPtr as an input (as a SEXP). However, the creation of XPtr from Rcpp::Function is something I want to do inside the package (i.e., the user should be able to input Function).
e.g, my package takes input generated as follows, which requires the user to write an additional function (here putFunPtrInXPtr()) and run the function in R to generate the XPtr (here my_ptr).
#include <Rcpp.h>
using namespace Rcpp;
typedef NumericVector (*funcPtr) (NumericVector y);
// [[Rcpp::export]]
NumericVector timesTwo(NumericVector x) {
return x * 2;
}
// [[Rcpp::export]]
XPtr<funcPtr> putFunPtrInXPtr() {
XPtr<funcPtr> testptr(new funcPtr(×Two), false);
return testptr;
}
/*** R
my_xptr <- putFunPtrInXPtr()
*/
How can I write something in which the user provides Function user_fun and I create the XPtr?
I tried
XPtr<funcPtr> package_fun(Function user_fun_input){
XPtr<funcPtr> testptr(new funcPtr(&user_fun_input), false);
}
user_fun_input is the parameter name inside the package function, but I am getting the following error
cannot initialize a new value of type 'funcPtr' (aka 'Vector<14> (*) (Vector<14>') with an rvalue of type 'Rcpp::Function *' (aka 'Function_Impl<PreserveStorage> *')
Also, there is an R step involved in creating the pointer, I am not sure how to implement that in the package (my .cpp file).
I think the creation of XPtr from Function could be confusing to the user, so better to just take Function as input and create the pointer to it, inside the package. I do use the XPtr in my package to gain speed.
Suggestions are most appreciated!
Related
When creating an R extension in C or C++, objects created in the compiled code need to be manually protected and unprotected from the garbage collector - e.g.:
SEXP some_func(SEXP inp)
{
SEXP some_vec = PROTECT(Rf_allocVector(REALSXP, 100));
// do something with 'some_vec' ...
UNPROTECT(1);
return some_vec;
}
Rcpp OTOH offers convenient classes which automatically handle the PROTECT and UNPROTECT calls, so one can safely do something like:
Rcpp::NumericVector some_func(SEXP inp)
{
Rcpp::NumericVector some_vec(100);
// do something with 'some_vec' ...
return some_vec;
}
Now, if I were to cast the Rcpp objects to generic SEXP, are they still auto protected? Example:
SEXP some_func(SEXP inp)
{
SEXP some_vec = Rcpp::NumericVector(100);
// do something with 'some_vec' ...
return some_vec;
}
Since some_vec was allocated as a specialized NumericVector but then casted to SEXP, does it still undergo automatic PROTECT/UNPROTECT, or do I need to do it manually?
And what about casting the other way around? E.g. is this safe?
Rcpp::NumericVector some_func(SEXP inp)
{
Rcpp::NumericVector some_vec = Rf_allocVector(REALSXP, 100);
// do something with 'some_vec' ...
return some_vec;
}
Yes as the only interface that there is from R uses SEXP .Call(SEXP ...). So every Rcpp object automatically gets transformed (a lot with implicit conversion but also via Rcpp::wrap(...)) and the protection is part of that.
You can easily verify that by for once creating a SEXP manually without the protection layer and R will tell you in R CMD check and/or crash.
From that you can conclude that Rcpp objects are correctly protected as this does not happen to them.
I have an object of class AI, which has a private non static void function which has a lot of arguments: minmax(double& val,double alpha, double beta, unsigned short depth, board* thisTurn); because this is a very time intensive function I want to use a number of threads to run it concurrently, therefor I must create a thread with this function inside another function inside the AI class;
According toThis question to make threads inside member functions containing non static member functions wiht no arguments of said class, one must call:
std::thread t(&myclass::myfunc,this);
And according to this tutorial threads of fucntions with multiple arguments can be created as such:
std::thread t(foo,4,5)
where the function 'foo' has 2 integer arguments
However I desire to mix these to things, to call a function which has arguments, which is also a non static member function, from inside the class that it is a member of, and i am not sure how to mix these to things.
I have off course tried (remember that it is inside a function inside the AI class):
std::thread t(&AI::minmax,val,alpha,beta,depth,thisTurn,this);
and
std::thread t(&AI::minmax,this,val,alpha,beta,depth,thisTurn);
But both cases fails with a compile error like this:
error: no matching constructor for initialization of 'std::thread'
candidate constructor template not viable: requires single argument '__f', but
7 arguments were provided
My question is therefor, if or if not, it is even possiple to -- from inside a member function of a class -- call a non static member function which has several arguments as a thread, and if this is the case, how it is done.
This question is however not wether or not it is a good idea to use multithreading in my specific case.
Edit
After doing some testing i realized that i can not call functions with arguments as threads at all, not even non-member functions with only one argument called directly from main, this was however solved by asking this other question where i realized that i simply need to add the flag -std=c++11 (because apparantly macs don't always use all c++11 features as standard) after doing so the answer works fine.
You need to wrap references using std::ref. The following example compiles fine:
#include <iostream>
#include <thread>
class board;
class AI
{
public:
void minmax(double& val, double alpha, double beta, unsigned short depth, board* thisTurn)
{
std::cout << "minmax" << std::endl;
}
void spawnThread()
{
double val;
double alpha;
double beta;
unsigned short depth;
board* thisTurn;
std::thread t(&AI::minmax, this, std::ref(val), alpha, beta, depth, thisTurn);
t.join();
}
};
int main()
{
AI ai;
ai.spawnThread();
}
I use Rcpp and RcppArmadillo and i have a "strange" problem. Lets say that i have function f1(). I include this function inside my package and run the command "R CMD INSTALL". After it's done i run a benchmark and i realise that f1 is slower about 100 microseconds inside the package than outside. So if a function wants 100ms to finish, in the package wants about 200+ms.
Code:
functions.cpp
vec f1(vec x){
vec F( x.size() );
for( int i = 0; i < x.size(); ++i ){
// do something
}
return F;
}
exportfunctions.cpp
vec f1(vec x);
RcppExport SEXP MyPackage_f1(SEXP xSEXP) {
BEGIN_RCPP
RObject __result;
RNGScope __rngScope;
traits::input_parameter< vec >::type x(xSEXP);
__result = wrap(f1(x));
return __result;
END_RCPP
}
exportfunctions.R
f1<- function(x) {
.Call( ' MyPackage_f1 ' , PACKAGE = ' MyPackage ', x )
}
An example of how my code is been written.
I believe the problem is that a function.R calls a function.cpp wich calls the final function. But why is this happening inside the package and not in sourceCpp. I can't understand the difference.
Briefly:
100ms is a non-issue. You are coming from R which is an interpreted environment
Calling a function involves several steps. Finding a function in a package involves some more.
See the documentation for .Call() to see how to minimize lookup.
See the documentation for NAMESPACE to set identifiers there too.
The latter two points should help close the gap between calling an ad-hoc function in the environment (which is cheaper) verses calling a function from the properly created infrastructure for doing so a.k.a. a package.
I came across a problem recently.
I have three files, A.h, B.cpp, C.cpp:
A.h
#ifndef __A_H__
#define __A_H__
int M()
{
return 1;
}
#endif // __A_H__
B.cpp
#include "A.h"
C.cpp
#include "A.h"
As I comile the three files by MSVC, there is a error:
C.obj : error LNK2005: "int __cdecl M(void)" (?M##YAHXZ) already defined in B.obj
It is easy understanding, as we know, B.obj has a symbol named "M", also C.obj has a "M".
Here the error comes.
However, if I change M method to a class which contain a method M like this below:
A.h
#ifndef __A_H__
#define __A_H__
class CA
{
public:
int M()
{
return 1;
}
};
#endif // __A_H__
there is no more errors!! Could somebody tell me what is happening?
If B.cpp and C.cpp include A.h, then both are compiled with your definition of M, so both object files will contain code for M. When the linker gathers all the functions, he sees that M is defined in two object files and does not know which one to use. Thus the linker raises an LNK2005.
If you put your function M into a class declaration, then the compiler marks/handles M as an inline function. This information is written into the object file. The linker sees that both object files contain a definition for an inline version of CA::M, so he assumes that both are equal and picks up randomly one of the two definitions.
If you had written
class CA {
public:
int M();
};
int CA::M()
{
return 1;
}
this would have caused the same problems (LNK2005) as your initial version, because then CA::M would not have been inline any more.
So as you might guess by now, there are two solutions for you. If you want M to be inlined, then change your code to
__inline int M()
{
return 1;
}
If you don't care about inlining, then please do it the standard way and put the function declaration into the header file:
extern int M();
And put the function definition into a cpp file (for A.h this would ideally be A.cpp):
int M()
{
return 1;
}
Please note that the extern is not really necessary in the header file.
Another user suggested that you write
static int M()
{
return 1;
}
I'd not recommend this. This would mean that the compiler puts M into both of your object files and marks M as being a function that is only visible in each object file itself. If the linker sees that a function in B.cpp calls M, it finds M in B.obj and in C.obj. Both have M marked as static, so the linker ignores M in C.obj and picks the M from B.obj. Vice versa if a function in C.cpp calls M, the linker picks the M from C.obj. You will end up with multiple definitions of M, all with the same implementation. This is a waste of space.
See http://faculty.cs.niu.edu/~mcmahon/CS241/c241man/node90.html how to do ifdef guards. You have to start with ifndef before the define.
Edit: Ah no, while your guard is wrong that's not the issue. Put static in front of your function to make it work. Classes are different because they define types.
I don't know what's under the hood, but if you don't need a class I guess that the compiler will automatically add the "extern" key to your functions, so you'll get the error including the header 2 times.
You can add the static keyword to M() method so you'll have only one copy of that function in memory and no errors at compile time.
By the way: I see you have a #endif, but not a #ifdef or #ifndef, is it a copy/paste error?
i have a trouble with a function template implementation in a .inl file (visual c++)
I have this on a header file.
math.h ->>
#ifndef _MATH_H
#define _MATH_H
#include <math.h>
template<class REAL=float>
struct Math
{
// inside this structure , there are a lot of functions , for example this..
static REAL sin ( REAL __x );
static REAL abs ( REAL __x );
};
#include "implementation.inl" // include inl file
#endif
and this is the .inl file.
implementation.inl -->>
template<class REAL>
REAL Math<REAL>::sin (REAL __x)
{
return (REAL) sin ( (double) __x );
}
template<class REAL>
REAL Math<REAL>::abs(REAL __x)
{
if( __x < (REAL) 0 )
return - __x;
return __x;
}
the sine function throw me an error at run time when i call it. However , abs function works
correctly.
i think the trouble is the call to one of the functions of the header math.h inside the .inl files
why I canĀ“t use math.h functions inside .inl file ?
The problem has nothing to do with .inl files - you're simply calling Math<REAL>::sin() recursively until the stack overflows. In MSVC 10 I even get a nice warning pointing that out:
warning C4717: 'Math<double>::sin' : recursive on all control paths, function will cause runtime stack overflow
Try:
return (REAL) ::sin ( (double) __x ); // note the `::` operator
Also, as a side note: the macro name _MATH_H is reserved for use by the compiler implementation. In many cases of using an implementation-reserved identifier you'd be somewhat unlucky to actually run into a conflict (though you should still avoid such names). However, in this case that name has a rather high chance of conflicting with the one that math.h might actually be using to prevent itself from being included multiple times.
You should definitely choose a different name that's unlikely to conflict. See What are the rules about using an underscore in a C++ identifier? for the rules.