<div dir="ltr"><div><div>Many thanks Krzysztof, your suggestion works.  I can explicitly create a 'new' arma::mat object and pass the resulting XPtr between functions.  I will work on making everything prettier and document for a submission to Rcpp Gallery unless someone is aware of one that already exists that I somehow overlooked.<br><br>// [[Rcpp::export]]<br>SEXP testXptr(NumericMatrix A)<br>{<br>    arma::mat *armaMat = new arma::mat(A.begin(),A.rows(), A.cols(), false);<br>    XPtr<arma::mat> pMat(armaMat);<br>    return(pMat);<br>}<br><br>// [[Rcpp::export]]<br>void testReturn(SEXP ptrA, int nr, int nc)<br>{<br>    XPtr<arma::mat> ptrB(ptrA);<br>    arma::mat B = arma::mat( (double *) ptrB->memptr(),<br>          nr,<br>          nc,<br>          false);<br>    B.print("copied matrix");<br>}<br><br></div>Regards,<br></div>Charles<br></div><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Jun 24, 2015 at 10:19 AM, Krzysztof Sakrejda <span dir="ltr"><<a href="mailto:krzysztof.sakrejda@gmail.com" target="_blank">krzysztof.sakrejda@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">Hi Charles, comments inline<br><div class="gmail_extra"><br><div class="gmail_quote"><span class="">2015-06-24 11:03 GMT-04:00 Charles Determan <span dir="ltr"><<a href="mailto:cdetermanjr@gmail.com" target="_blank">cdetermanjr@gmail.com</a>></span>:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div>The fastLm examples are nice but they don't contain anything relating to passing an XPtr between functions.  Regarding your comment about making an XPtr around arma::mat 'innards' I'm not sure I fully understand.  I tried creating an XPtr around a arma::mat but no success on passing the object between functions.  It still returns that ~zeros.<br><br>// [[Rcpp::export]]<br>SEXP testXptr(SEXP A)<br>{<br>    arma::Mat<double> armaMat = as<arma::mat>(A);<br>    XPtr<arma::mat> pMat(&armaMat);<br>    return(pMat);    <br>}<br></div></div></blockquote><div><br></div></span><div>When testXptr returns, armaMat is gone so it doesn't matter what you do with pMat.  You need to use "new" to create armaMat and hand it over to XPtr as above.  Then XPtr is returned to R. When XPtr is returned to R it's protected from R's garbage collection by having a reference (reference? something like that) to it in R.  armaMat lives on since it was created with "new".  When you delete the XPtr in R, _it_ gets garbage-collected and the destructor for XPtr calls "delete" on armaMat.  Then armaMat is gone and you don't have a memory leak.  So the scheme is:<br><br></div><div>1) Create object of class Whatever in C++ using new.<br></div><div>2) Wrap object in XPtr<Whatever><br></div><div>3) Return XPTr<Whatever> to R and save it to a variable.<br></div><div>4) Pass XPtr<Whatever> to any functions that need the object of class Whatever<br></div><div>5) When you don't need the object of class Whatever, remove  XPtr<Whatever> from the R session<br></div><div>6) R does gc on XPtr<Whatever>, which has a destructor.<br></div><div>7) Destructor from XPtr<Whatever> does "delete" on object of class Whatever.<br><br></div><div>Been a few months since I used this but I'm sure someone will correct me if I'm not quite right here.  There really ought to be (and might already be) an Rcpp gallery item about this process.  I'll sign up to make on later this summer :)<span class="HOEnZb"><font color="#888888"><br><br></font></span></div><span class="HOEnZb"><font color="#888888"><div>Krzysztof<br></div></font></span><div><div class="h5"><div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div><br>// [[Rcpp::export]]<br>void testReturn(SEXP ptrA, int nr, int nc)<br>{<br>    XPtr<arma::mat> ptrB(ptrA);<br>    arma::mat B = arma::mat( (double *) ptrB->memptr(),<br>          nr,<br>          nc,<br>          false);<br>    B.print("copied matrix");<br>}<span><font color="#888888"><br><br></font></span></div><span><font color="#888888">Charles<br></font></span></div><div><div><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Jun 24, 2015 at 8:32 AM, Dirk Eddelbuettel <span dir="ltr"><<a href="mailto:edd@debian.org" target="_blank">edd@debian.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span><br>
On 24 June 2015 at 08:22, Charles Determan wrote:<br>
| Thank you John,<br>
|<br>
| I am familiar with bigmemory (I am one of the current developers actually). <br>
| The project I am working on doesn't need the shared memory aspect so was<br>
| intending to avoid the dependency and just leverage the more familiar and<br>
| developed Armadillo library.  However your response informs me that I did not<br>
| fully understand how armadillo objects are handled.  I have some other ideas<br>
| with how I can address my problem but this was something I was hoping to apply<br>
| both for this project and for the sake of learning.<br>
<br>
</span>Look at more current RcppArmadillo examples, and in particular _all_ the<br>
variants of the fastLm benchmark in examples.  By doing the explicit cast,<br>
you _forced_ a copy which may then have destroyed the Xptr link.  I *think*<br>
you could just do XPtr around arma::mat innards.  I would actually be<br>
interested in having something somewhere between bigmemory (where I was one<br>
of the first external users) and what we have in RcppArmadillo.<br>
<br>
Dirk, during a break of Rcpp class in Zuerich<br>
<span><br>
| Regards,<br>
| Charles<br>
|<br>
| On Tue, Jun 23, 2015 at 9:29 PM, John Buonagurio <<a href="mailto:jbuonagurio@exponent.com" target="_blank">jbuonagurio@exponent.com</a>><br>
| wrote:<br>
|<br>
|     Hi Charles,<br>
|<br>
|     > SEXP testXptr(SEXP A)<br>
|     > {<br>
|     >     arma::Mat<double> armaMat = Rcpp::as<arma::Mat<double> >(A);<br>
|     >     Rcpp::XPtr<double> pMat(armaMat.memptr());<br>
|     >     return(pMat);<br>
|     > }<br>
|<br>
|     armaMat is on the stack, so the Armadillo memptr is no longer valid when<br>
|     you return from the testXptr function.<br>
|<br>
|     One simple solution in your case would be to dynamically allocate with<br>
|     "new" [e.g. arma::mat *A = new arma::mat(...);], though I can't tell you<br>
|     off hand how object lifetime is managed with Armadillo objects.<br>
|<br>
|     If you're trying to preserve a matrix across function calls in R, have you<br>
|     looked into bigmemory? <a href="http://gallery.rcpp.org/articles/" rel="noreferrer" target="_blank">http://gallery.rcpp.org/articles/</a><br>
|     using-bigmemory-with-rcpp/<br>
|<br>
|     John<br>
|<br>
|<br>
|<br>
</span>| _______________________________________________<br>
| Rcpp-devel mailing list<br>
| <a href="mailto:Rcpp-devel@lists.r-forge.r-project.org" target="_blank">Rcpp-devel@lists.r-forge.r-project.org</a><br>
| <a href="https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel" rel="noreferrer" target="_blank">https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel</a><br>
<div><div><br>
--<br>
<a href="http://dirk.eddelbuettel.com" rel="noreferrer" target="_blank">http://dirk.eddelbuettel.com</a> | @eddelbuettel | <a href="mailto:edd@debian.org" target="_blank">edd@debian.org</a><br>
</div></div></blockquote></div><br></div>
</div></div><br>_______________________________________________<br>
Rcpp-devel mailing list<br>
<a href="mailto:Rcpp-devel@lists.r-forge.r-project.org" target="_blank">Rcpp-devel@lists.r-forge.r-project.org</a><br>
<a href="https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel" rel="noreferrer" target="_blank">https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel</a><br></blockquote></div></div></div><br></div></div>
</blockquote></div><br></div>