Call and memory
On Fri, 9 Jan 2004, Thomas Lumley wrote:
On Fri, 9 Jan 2004, Bob Wheeler wrote:
I use a large real matrix, X, in C code that is passed from R and
transposed in place in the C code. I would like to conserve memory and,
if possible, allocate space for only one copy of X -- hence I would like
to pass a pointer to the data in the X object to the C code.
The Writing R Extensions manual says that neither .Call nor .External
copy their arguments. They also say that these arguments should be
treated as read only.
Fine, but in testing I seem to be able to transpose very large X's in
place, in C code without an error. This leads me to assume that the
manual was just giving good advice about treating arguments as read
only. However, I find that I have done nothing to the X in R. It seems
that a copy has been made after all. I may as well call the code with .C
and avoid the use of macros.
Could someone please point out the error in my thinking or suggest a way
to accomplish my goal?
My code follows:
"mListTest" <-
function(X,N,k) {
.Call("mList",as.double(X),as.integer(N),as.integer(k));
}
as.double(X) returns a copy of X, so you are only passing a copy to C.
storage.mode(X) <- "double" is the standard paradigm to avoid an copy here if not needed (even with .C, which would make two copies of X on entry and one on exit). Both arima() and the Kalman fitering code used by StructTS() makes use of the ability of .Call to alter its arguments, so the advice given is definitely right. It is hard to predict when R will make a copy, not least because from time to time we spot an unnecessary copy or add a necessary one. So if you do want .Call to alter its arguments you need to test your assumptions (and retest when R is updated).
Brian D. Ripley, ripley at stats.ox.ac.uk Professor of Applied Statistics, http://www.stats.ox.ac.uk/~ripley/ University of Oxford, Tel: +44 1865 272861 (self) 1 South Parks Road, +44 1865 272866 (PA) Oxford OX1 3TG, UK Fax: +44 1865 272595