[Rcpp-devel] Some questions regarding internals of Rcpp objects
Dirk Eddelbuettel
edd at debian.org
Fri Aug 5 18:50:03 CEST 2011
Hi Ulrich,
These are really several questions. I'll try to address them all, with some
luck maybe Romain, Doug, Christian, ... will correct or complement as needed.
On 5 August 2011 at 11:45, Ulrich Bodenhofer wrote:
| Dear list members,
|
| I have started developing a package using the latest version of Rcpp just
| recently, so I am more or less an Rcpp newbie. Since I am not sufficiently
| proficient in advanced C++ (and admittedly too lazy too) to analyze the Rcpp
| source code, I have some questions regarding what actually happens inside Rcpp.
| Let me bother you with an example:
|
| RcppExport SEXP test(SEXP mat)
| {
| BEGIN_RCPP
| Rcpp::NumericMatrix matC(mat);
| Rcpp::NumericMatrix matD(mat);
|
| matC(1, 1) = 1;
| matD(1, 1) = -matD(1, 1);
|
| return(matC);
| END_RCPP
| }
|
| If I call this function on some matrix, then the function returns the input
| matrix with its element [2, 2] set to 1, but that's all. The change in matD
| only seems to have an effect on the local copy matD. If I replace "return(matC)
| " by "return(matD)", then the function returns the input matrix with the sign
| of its element [2, 2] inverted, so the change in matC has no effect. That Rcpp
| creates local copies, i.e. that matC and matD are independent objects each
| holding local copies of the argument mat, would perfectly explain these
This has been discussed here before. The matrices both receive a _pointer_
(as a SEXP is a pointer) to the original memory of the R-level matrix you
pass in.
You need to explicitly request deep copies via clone() if you want that. See
this variant:
R> fun <- cxxfunction(signature(mat="numeric"), plugin="Rcpp", body='
+ Rcpp::NumericMatrix matC(mat);
+ Rcpp::NumericMatrix matD(mat);
+
+ matC(1, 1) = 1;
+ matD(1, 1) = -matD(1, 1);
+
+ return(Rcpp::List::create(Rcpp::Named("C")=matC,
+ Rcpp::Named("D")=matD));
+ ');
R> fun(matrix(42,2,2))
$C
[,1] [,2]
[1,] 42 42
[2,] 42 -1
$D
[,1] [,2]
[1,] 42 42
[2,] 42 -1
R>
So C and D are really the same thing.
| results. Previously, however, I thought Rcpp would only wrap an R/SEXP object
| into an Rcpp object without making a copy. If it was so, no matter whether the
| function returns matC or matD, the function would return the input matrix with
| -1 on position [2, 2]. Did I get this point wrong? I suppose it would save time
| and memory not to create a copy, in particular, since arguments to functions
| are local copies already. Is there a way to avoid copying?
|
| A related question is what the "=" operator does. Does
|
| Rcpp::NumericVector x = ...;
|
| create a copy or is it only a pointer that is assigned?
IIRC the pointer is copied, yet still points to same memory address.
| My final question concerns the "longevity" of Rcpp objects. Suppose I do the
| following:
|
| {
| Rcpp::NumericVector vec(10);
| double *p = vec.begin();
| }
|
| Can I use *p outside this block or is the pointer killed along with the
| variable vec after the block is closed? According to my limited knowledge, I
p as a variable is gone outside of this { } scope. So is vec but as you say ...
| would assume that it is only the reference vec that is not available outside
| the block, but that the corresponding R object still exists and will be deleted
| by the R garbage collector only after the whole function has terminated.
... we do not explicitly destroy in the destructor but let R take care of
it. So it will live "some random amount" of time you have no control over. Eeek.
In a nutshell, if you want longer-living objects, assign in R before you call
a function -- you are pretty much guaranteed it will be there.
If you need persistence between different calls from R you need an object
that persists, and there are many possible C++ tricks to do that.
| Any help is gratefully appreciated! I am sorry if these are stupid questions or
| if any of them have been discussed previously.
Great questions, but some of the material has been discussed before. We
probably need a better FAQ or better search engine...
Cheers, Dirk
|
| Thanks and best regards,
| Ulrich
|
|
| ----------------------------------------------------------------------
| _______________________________________________
| Rcpp-devel mailing list
| Rcpp-devel at lists.r-forge.r-project.org
| https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel
--
Gauss once played himself in a zero-sum game and won $50.
-- #11 at http://www.gaussfacts.com
More information about the Rcpp-devel
mailing list