1

Original motivation behind this is that I have a dynamically sized array of floats that I want to pass to R through Rcpp without either incurring the cost of a zeroing out nor the cost of a deep copy.

Originally I had thought that there might be some way to take heap allocated array, make it aware to R's gc system and then wrap it with other data to create a "Rcpp::NumericVector" but it seems like that that's not possible - or doable with my current knowledge.

However and correct me if I'm wrong it looks like simply constructing a NumericVector with a size N and then using it as an N sized allocation will call R.h's Rf_allocVector and that itself does not either zero out the allocated array - I tested it on a small C program that gets dyn.loaded into R and it looks like garbage values. I also took a peek at the assembly and there doesn't seem to be any zeroing out.

Can anyone confirm this or offer any alternate solution?

Terrryyy1
  • 31
  • 4

1 Answers1

1

Welcome to StackOverflow.

You marked this rcpp but that is a function from the C API of R -- whereas the Rcpp API offers you its constructors which do in fact set the memory tp zero:

> Rcpp::cppFunction("NumericVector goodVec(int n) { return NumericVector(n); }")
> sum(goodVec(1e7))
[1] 0
> 

This creates a dynamically allocated vector using R's memory functions. The vector is indistinguishable from R's own. And it has the memory set to zero as we use R_Calloc, which is documented in Writing R Extension to setting the memory to zero. (We may also use memcpy() explicitly, you can check the sources.)

So in short, you just have yourself confused over what the C API of R, as well as Rcpp offer, and what is easiest to use when. Keep reading documentation, running and writing examples, and studying existing code. It's all out there!

Dirk Eddelbuettel
  • 360,940
  • 56
  • 644
  • 725
  • Thanks so much for the welcome! Ahh I must've missed the part where we Calloc but having tested it (which I really should've done immediately) its plainly calloced. Is there anything to worry about if I use the R.h Rf_allocvector call inside a Rcpp codebase behind extern C? Or moreover is there an easy way to allocate a (large) array of memory inside Rcpp that can be passed back to R via its base pointer address? – Terrryyy1 May 26 '22 at 13:11
  • Why would you want to alloc yourself when you have `Rcpp` and its vectors, matrices, list, ... objects that are R objects? Your design choice seem odd, but a short comment box is not the place to discuss this. Basically all design have been made by now, I would ask on `rcpp-devel`. (And yes plain C++ STL alloc is also possible by again then you get C++ containers and have no need for `*alloc()` either.) Lastly, if my answer helps your question it is customary to upvote (click on 'up'-triangle) and/or accept (click on 'tick') it. – Dirk Eddelbuettel May 26 '22 at 13:18
  • My apologies, definitely a helpful answer and I think my upvote will come around once I hit 15 reputation. I definitely want to take Rcpp as a fixed object and I only wonder if I can construct a solution within the confines that you guys and Rcpp have set out for me. – Terrryyy1 May 26 '22 at 13:34
  • As for why I want to alloc myself, I just want to avoid zeroing since I want to use a pretty sizeable chunk of memory, like 10 or so allocations of 2^32-1 bytes, so like 170gb of RAM and even though testing has shown that the calloc is relatively fast, it clocks in at 18 seconds for a 2e8 size array of doubles, I'm not knowledgeable enough to know whether the OS pays the price for me on every page fault. Also just curiousity somewhat as well. With C++ stl allocs I have to pay a copy price on exit which I'd also like to avoid – Terrryyy1 May 26 '22 at 13:36
  • We have an attribute `no_init` you can set to not init. Personally I do not use it but I recall you can. And you still haven't upvoted which you can with any reputation level. – Dirk Eddelbuettel May 26 '22 at 13:50
  • 1
    https://imgur.com/VPxc8mh <- sorry I really can't upvote. Thanks for the no_init function, looks perfect! For future me: Something like this works perfeclty `Rcpp::cppFunction("NumericVector goodVec(int n) { return no_init(n); }")` – Terrryyy1 May 26 '22 at 14:01
  • My bad, I confused upvote and accept. Glad you're set now. The rcpp-devel list is still good (and low volume!) so come and lurk for a bit. – Dirk Eddelbuettel May 26 '22 at 14:34