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.
// [[Rcpp::export]] SEXP testXptr(NumericMatrix A) { arma::mat *armaMat = new arma::mat(A.begin(),A.rows(), A.cols(), false); XPtr<arma::mat> pMat(armaMat); return(pMat); } // [[Rcpp::export]] void testReturn(SEXP ptrA, int nr, int nc) { XPtr<arma::mat> ptrB(ptrA); arma::mat B = arma::mat( (double *) ptrB->memptr(), nr, nc, false); B.print("copied matrix"); } Regards, Charles On Wed, Jun 24, 2015 at 10:19 AM, Krzysztof Sakrejda < krzysztof.sakre...@gmail.com> wrote: > Hi Charles, comments inline > > 2015-06-24 11:03 GMT-04:00 Charles Determan <cdeterma...@gmail.com>: > >> 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. >> >> // [[Rcpp::export]] >> SEXP testXptr(SEXP A) >> { >> arma::Mat<double> armaMat = as<arma::mat>(A); >> XPtr<arma::mat> pMat(&armaMat); >> return(pMat); >> } >> > > 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: > > 1) Create object of class Whatever in C++ using new. > 2) Wrap object in XPtr<Whatever> > 3) Return XPTr<Whatever> to R and save it to a variable. > 4) Pass XPtr<Whatever> to any functions that need the object of class > Whatever > 5) When you don't need the object of class Whatever, remove > XPtr<Whatever> from the R session > 6) R does gc on XPtr<Whatever>, which has a destructor. > 7) Destructor from XPtr<Whatever> does "delete" on object of class > Whatever. > > 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 :) > > Krzysztof > > > >> >> // [[Rcpp::export]] >> void testReturn(SEXP ptrA, int nr, int nc) >> { >> XPtr<arma::mat> ptrB(ptrA); >> arma::mat B = arma::mat( (double *) ptrB->memptr(), >> nr, >> nc, >> false); >> B.print("copied matrix"); >> } >> >> Charles >> >> On Wed, Jun 24, 2015 at 8:32 AM, Dirk Eddelbuettel <e...@debian.org> >> wrote: >> >>> >>> On 24 June 2015 at 08:22, Charles Determan wrote: >>> | Thank you John, >>> | >>> | I am familiar with bigmemory (I am one of the current developers >>> actually). >>> | The project I am working on doesn't need the shared memory aspect so >>> was >>> | intending to avoid the dependency and just leverage the more familiar >>> and >>> | developed Armadillo library. However your response informs me that I >>> did not >>> | fully understand how armadillo objects are handled. I have some other >>> ideas >>> | with how I can address my problem but this was something I was hoping >>> to apply >>> | both for this project and for the sake of learning. >>> >>> Look at more current RcppArmadillo examples, and in particular _all_ the >>> variants of the fastLm benchmark in examples. By doing the explicit >>> cast, >>> you _forced_ a copy which may then have destroyed the Xptr link. I >>> *think* >>> you could just do XPtr around arma::mat innards. I would actually be >>> interested in having something somewhere between bigmemory (where I was >>> one >>> of the first external users) and what we have in RcppArmadillo. >>> >>> Dirk, during a break of Rcpp class in Zuerich >>> >>> | Regards, >>> | Charles >>> | >>> | On Tue, Jun 23, 2015 at 9:29 PM, John Buonagurio < >>> jbuonagu...@exponent.com> >>> | wrote: >>> | >>> | Hi Charles, >>> | >>> | > SEXP testXptr(SEXP A) >>> | > { >>> | > arma::Mat<double> armaMat = Rcpp::as<arma::Mat<double> >(A); >>> | > Rcpp::XPtr<double> pMat(armaMat.memptr()); >>> | > return(pMat); >>> | > } >>> | >>> | armaMat is on the stack, so the Armadillo memptr is no longer >>> valid when >>> | you return from the testXptr function. >>> | >>> | One simple solution in your case would be to dynamically allocate >>> with >>> | "new" [e.g. arma::mat *A = new arma::mat(...);], though I can't >>> tell you >>> | off hand how object lifetime is managed with Armadillo objects. >>> | >>> | If you're trying to preserve a matrix across function calls in R, >>> have you >>> | looked into bigmemory? http://gallery.rcpp.org/articles/ >>> | using-bigmemory-with-rcpp/ >>> | >>> | John >>> | >>> | >>> | >>> | _______________________________________________ >>> | Rcpp-devel mailing list >>> | Rcpp-devel@lists.r-forge.r-project.org >>> | >>> https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel >>> >>> -- >>> http://dirk.eddelbuettel.com | @eddelbuettel | e...@debian.org >>> >> >> >> _______________________________________________ >> Rcpp-devel mailing list >> Rcpp-devel@lists.r-forge.r-project.org >> https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel >> > >
_______________________________________________ Rcpp-devel mailing list Rcpp-devel@lists.r-forge.r-project.org https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel