[Rcpp-devel] Problem passing Armadillo objects back to R

Romain Francois romain at r-enthusiasts.com
Wed Apr 6 13:22:39 CEST 2011


Hmmmmmmmm. I'm afraid I can't fix this.

Here is the story: both wrap(X) and wrap(X) create a new SEXP and 
allocate memory. When wrap(Y) is called, since the created object is 
large, R calls the GC to collect unprotected SEXP to free some space. So 
my guess is that at that point the SEXP that is generated by wrap(X) is 
collected since it is not protected.

I can not deal with this inside ::create, because it is too late.


A Workaround is to use this :

return Rcpp::List::create(
Rcpp::Named("X") = X,
Rcpp::Named("Y") = Y
);

i.e. use the implicit wrap. here wrap will be called much later and 
things are fine.


The issue is that when calling wrap it creates an unprotected SEXP, and 
Rcpp is not responsible for these. If the programmer passes an 
unprotected SEXP to ::create, it is his responsability to protect it. So 
another alternative would be:

SEXP xx = PROTECT( wrap( X ) ) ;
SEXP yy = PROTECT( wrap( Y ) ) ;
Rcpp::List result =  Rcpp::List::create(
Rcpp::Named("X") = xx,
Rcpp::Named("Y") = yy
);
UNPROTECT(2) ;
return res ;

yes, this is ugly.

Romain

Le 06/04/11 11:42, Romain Francois a écrit :
>
> Good news. I can reproduce it.
> Bas news. This is likely a PROTECT problem with the Rcpp::List constructor.
>
> Wearing my bugbuster costume, and getting ready for a fight.
>
> Romain
>
> Le 07/03/11 23:03, "Günter J. Hitsch" a écrit :
>>
>> I'm new to Rcpp and RcppArmadillo---so far I like it a lot! Thanks to
>> the developers for their good work.
>>
>> I run into a peculiar kind of problem when I try to pass a "large"
>> Armadillo object back to R. Here's some code to replicate the problem in
>> stylized form:
>>
>>
>> extern "C" SEXP testFun(SEXP L_)
>> {
>> const long L = Rcpp::as<long>(L_);
>> arma::mat X(L,1);
>> arma::mat Y(L,1);
>> X.fill(1);
>> Y.fill(2);
>> return Rcpp::List::create(
>> Rcpp::Named("X") = Rcpp::wrap(X),
>> Rcpp::Named("Y") = Rcpp::wrap(Y)
>> );
>> }
>>
>>
>> I compile (both using g++ and the Intel Compiler --- choice of compiler
>> makes no difference) and then call from R:
>>
>>
>> L = 1000000
>> ret = .Call("testFun", as.integer(L))
>> print(ret$X[1:5,])
>> print(ret$Y[1:5,])
>>
>>
>> Here's what I often get as output:
>>
>> [1] 1 1 1 1 1
>> [1] 1 1 1 1 1
>>
>> However, the second rows should be all 2's!
>>
>> When I try to pass smaller matrices, for example by setting L=100000,
>> the problem goes away:
>>
>> [1] 1 1 1 1 1
>> [1] 2 2 2 2 2
>>
>>
>> Also, the problem does not arise when I create and pass pack objects of
>> type Rcpp::NumericMatrix; so far I've see the problem only with
>> Armadillo objects. I've encountered this on two Macs running OS X
>> 10.6.6, R 2.12.2, and I'm using the latest versions of Rcpp and
>> RcppArmadillo.
>>
>> Help on this matter is appreciated!
>>
>> Günter
>>
>>
>>
>> _______________________________________________
>> 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
>
>


-- 
Romain Francois
Professional R Enthusiast
+33(0) 6 28 91 30 30
http://romainfrancois.blog.free.fr
http://romain-francois.com
|- http://bit.ly/fhqbRC : Rcpp workshop in Chicago on April 28th
|- http://bit.ly/dFyZGB : Hydraulique au Montpellier Comedie Club
`- http://bit.ly/eVXit9 : Eponyme : 40 minutes stand up




More information about the Rcpp-devel mailing list