Hi Romain,
I considered the implicit use of Rcpp::as<>() inside of the arma::mat()
constructor. My target was to reuse memory and try to use a very simple
setting, i.e. (at least in my opinion) not too much lines of code.
You answered to my question
"On the other side I then assume, that the Rcpp:as<class M>() function makes a
cast and therefore creates a copy with new allocated memory of the type
included in M? Therefore a reuse of memory with this function is not possible":
Depends what is M, but most of the time yes, as<> copies data.
What I then tried, was this:
setClass("myclass", representation(par = "list"))
l <- list(lambda = array(0, dim = c(10,2)))
mclass <- new("myclass", par = l)
cfunction <- cxxfunction(signature(myClass_R = "array"), body = 'Rcpp::S4
myclass(myClass_R); Rcpp::List parL((SEXP) myclass.slot("par")); arma::mat
armaPar(Rcpp::as<Rcpp::NumericMatrix>(parL["lambda"]).begin(), 10, 2, false,
true); armaPar(0,0) = 1.2 ;return Rcpp::wrap(myclass);', plugin =
"RcppArmadillo")
cfunction(mclass)
An object of class "myclass"
Slot "par":
$lambda
[,1] [,2]
[1,] 1.2 0
[2,] 0.0 0
[3,] 0.0 0
[4,] 0.0 0
[5,] 0.0 0
[6,] 0.0 0
[7,] 0.0 0
[8,] 0.0 0
[9,] 0.0 0
[10,] 0.0 0
So, it seems, that calling Rcpp::as<>() implicitly inside the arma::mat()
constructor, enables the reuse of memory with only a few lines of code, which
is pretty nice. So in case of M being Rcpp::NumericMatrix, Rcpp::as<>() seems
not to copy data. But it also could be, that I misunderstood your answer above,
or that we were talking about two different things there. In this case please
apologize my confusion.
Best
Simon
On Jun 8, 2013, at 8:08 AM, Romain Francois <[email protected]> wrote:
> Le 07/06/13 16:07, Simon Zehnder a écrit :
>> Hi Romain,
>>
>> thanks for this precise answer. So the suggested methods below will work
>> without making a copy of the object.
>
> yes
>
>> What is about the implicit call of Rcpp::as<>() inside arma::mat()? It is a
>> very convenient way to create an arma object reusing memory and it seems to
>> work just fine.
>
> I don't know what you are talking about.
>
>> Best
>>
>> Simon
>> On Jun 7, 2013, at 3:47 PM, Romain Francois <[email protected]> wrote:
>>
>>> Le 07/06/13 15:14, Simon Zehnder a écrit :
>>>> Hi Romain, hi Dirk,
>>>>
>>>> sorry for posting here again, but I found something in some way connected
>>>> to this discussion - and pretty interesting concerning the Rcpp::as<>()
>>>> function:
>>>>
>>>> 1. I create a class containing a list:
>>>>
>>>> setClass("myclass", representation(par = "list"))
>>>>
>>>> l <- list(lambda = array(0, dim = c(10,2)))
>>>>
>>>> mclass <- new("myclass", par = l)
>>>>
>>>> 2. I compile a C++ function, that should reuse the memory of 'lambda'
>>>> inside the list:
>>>>
>>>> library(inline)
>>>> cfunction <- cxxfunction(signature(myClass_R = "array"), body = 'Rcpp::S4
>>>> myclass(myClass_R); Rcpp::List parL((SEXP) myclass.slot("par")); arma::mat
>>>> armaPar(parL["lambda"].begin(), 10, 2, false, true); armaPar(0,0) = 1.2
>>>> ;return Rcpp::wrap(myclass);', plugin = "RcppArmadillo")
>>>>
>>>> I get an error:
>>>>
>>>> Error in compileCode(f, code, language = language, verbose = verbose) :
>>>> Compilation ERROR, function(s)/method(s) not created!
>>>> file6fc2ab39965.cpp: In function ‘SEXPREC* file6fc2ab39965(SEXP)’:
>>>> file6fc2ab39965.cpp:30:109: error: ‘Rcpp::Vector<19>::NameProxy’ has no
>>>> member named ‘begin’
>>>> Rcpp::S4 myclass(myClass_R); Rcpp::List parL((SEXP) myclass.slot("par"));
>>>> arma::umat armaPar(parL["lambda"].begin(), 100, 10, false, true);
>>>> armaPar(0,0) = 1.2 ;return Rcpp::wrap(myclass);
>>>
>>> What you get from doing parL["lambda"] is an object of class NameProxy, it
>>> will be converted to the appropioate class later. NameProxy have no .begin
>>> method.
>>>
>>> Do this:
>>>
>>> NumericVector tmp = parL["lambda"] ;
>>> arma::mat armaPar(tmp.begin(), 10, 2, false, true);
>>>
>>> This will not make copies of the data.
>>>
>>> If thius feels like too much to type, just stuff this into a function:
>>>
>>> inline arma::mat convert( SEXP x ){
>>> NumericVector tmp = parL["lambda"] ;
>>> return arma::mat(tmp.begin(), 10, 2, false, true);
>>> }
>>>
>>> and call :
>>>
>>> arma::mat armaPar = convert( parL["lambda"] ) ;
>>>
>>> There is a chance convert won't make a copy thanks to RVO.
>>> ^
>>>> make: *** [file6fc2ab39965.o] Error 1
>>>> In addition: Warning message:
>>>> running command '/Library/Frameworks/R.framework/Resources/bin/R CMD SHLIB
>>>> file6fc2ab39965.cpp 2> file6fc2ab39965.cpp.err.txt' had status 1
>>>>
>>>> -----------------------------------------------------------
>>>>
>>>> It seems, that the SEXP inside the List is not yet an Rcpp::NumericMatrix,
>>>> so I make it explicit to the arma::mat() constructor:
>>>>
>>>> cfunction <- cxxfunction(signature(myClass_R = "array"), body = 'Rcpp::S4
>>>> myclass(myClass_R); Rcpp::List parL((SEXP) myclass.slot("par")); arma::mat
>>>> armaPar(Rcpp::as<Rcpp::NumericMatrix>(parL["lambda"]).begin(), 100, 10,
>>>> false, true); armaPar(0,0) = 1.2 ;return Rcpp::wrap(myclass);', plugin =
>>>> "RcppArmadillo")
>>>>
>>>> That compiles.
>>>>
>>>> If we let it run it gives us:
>>>>
>>>> cfunction(mclass)
>>>> An object of class "myclass"
>>>> Slot "par":
>>>> $lambda
>>>> [,1] [,2]
>>>> [1,] 1.2 0
>>>> [2,] 0.0 0
>>>> [3,] 0.0 0
>>>> [4,] 0.0 0
>>>> [5,] 0.0 0
>>>> [6,] 0.0 0
>>>> [7,] 0.0 0
>>>> [8,] 0.0 0
>>>> [9,] 0.0 0
>>>> [10,] 0.0 0
>>>>
>>>> So, we can see, that implicitly calling Rcpp::as<>() inside the
>>>> constructor arma::mat() avoids a copy by Rcpp::as<>() - which is just
>>>> beautiful!
>>>>
>>>>
>>>> Best
>>>>
>>>> Simon
>>>>
>>>>
>>>>
>>>>
>>>>
>>>> On Jun 7, 2013, at 1:19 PM, Simon Zehnder <[email protected]> wrote:
>>>>
>>>>> Thank you Romain!
>>>>>
>>>>> All clear now!
>>>>>
>>>>>
>>>>> Best
>>>>>
>>>>> Simon
>>>>>
>>>>> On Jun 7, 2013, at 1:13 PM, Romain Francois <[email protected]>
>>>>> wrote:
>>>>>
>>>>>> Le 07/06/13 13:09, Simon Zehnder a écrit :
>>>>>>> HI Dirk, hi Romain,
>>>>>>>
>>>>>>> allright, this is now clear to me, if I want to reuse memory, the
>>>>>>> allocated memory from R (so implicitly in C) must of course have the
>>>>>>> same type - otherwise the memory has a different size.
>>>>>>
>>>>>> so far, this is obvious.
>>>>>>
>>>>>>> On the other side I then assume, that the Rcpp:as<class M>() function
>>>>>>> makes a cast and therefore creates a copy with new allocated memory of
>>>>>>> the type included in M? Therefore a reuse of memory with this function
>>>>>>> is not possible.
>>>>>>
>>>>>> Depends what is M, but most of the time yes, as<> copies data.
>>>>>>
>>>>>>> Best
>>>>>>>
>>>>>>> Simon
>>>>>>>
>>>>>>>
>>>>>>> On Jun 6, 2013, at 8:31 PM, Dirk Eddelbuettel <[email protected]> wrote:
>>>>>>>
>>>>>>>>
>>>>>>>> On 6 June 2013 at 13:17, Dirk Eddelbuettel wrote:
>>>>>>>> |
>>>>>>>> | On 6 June 2013 at 19:05, Simon Zehnder wrote:
>>>>>>>> | | sorry I had overseen this message from you. Okay, so the explicit
>>>>>>>> cast to SEXP together with the assignment operator makes the deal. But
>>>>>>>> it still includes the reuse of memory right, i.e. the '=' does not
>>>>>>>> call the copy constructor?
>>>>>>>> |
>>>>>>>> | But how could an _unsigned int_ from Armadillo possibly have the
>>>>>>>> same value
>>>>>>>> | as a _signed int_ in R?
>>>>>>>> |
>>>>>>>> | Either you are efficient (no copy), or you are correct (with a
>>>>>>>> copy). I do
>>>>>>>> | not see how you could have both.
>>>>>>>>
>>>>>>>> Sorry -- please ignore this message.
>>>>>>>>
>>>>>>>> I had mistakenly assumed that you were still thinking about arma::umat
>>>>>>>> to
>>>>>>>> integer. For direct int-to-int this is indeed efficient just like the
>>>>>>>> double-to-double is for arma::mat to NumericMatrix (and dito for
>>>>>>>> vectors). I
>>>>>>>> though that was a given -- maybe need to make this (even) more
>>>>>>>> explicit in
>>>>>>>> the documentation.
>>>>>>>>
>>>>>>>> So in sum: you get correct and efficient behaviour if and only if you
>>>>>>>> stick
>>>>>>>> with the types natively supported in Armadillo and R.
>>>>>>>>
>>>>>>>> Dirk
>>>>>>>>
>
>
> --
> Romain Francois
> Professional R Enthusiast
> +33(0) 6 28 91 30 30
>
> R Graph Gallery: http://gallery.r-enthusiasts.com
>
> blog: http://blog.r-enthusiasts.com
> |- http://bit.ly/Zs97qg : highlight 0.4.1
> `- http://bit.ly/10X94UM : Mobile version of the graph gallery
>
_______________________________________________
Rcpp-devel mailing list
[email protected]
https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel