[Rcpp-devel] can one modify array in R memory from C++ without copying it?

Douglas Bates bates at stat.wisc.edu
Fri Nov 4 16:03:41 CET 2011


On Fri, Nov 4, 2011 at 8:36 AM, Dirk Eddelbuettel <edd at debian.org> wrote:
>
> On 4 November 2011 at 16:56, Darren Cook wrote:
> | > Not a bug, this is expected behaviour.
> |
> | Hello Romain,
> | I did not mean the behaviour is a bug; I mean it is going to cause bugs.
> | I was wondering if there is a way to stop the implicit data coercion,
> | forcing the programmer to request it explicitly.
>
> R does exactly that too
>
> R> a <- 1
> R> typeof(a)
> [1] "double"
> R> a <- 1L
> R> typeof(a)
> [1] "integer"
> R>
>
> and Rcpp uses Proxy Classes so this is the Right Thing (TM) to do.  We think,
> at least.
>
> | E.g. Are the implicit type conversions happening with some extra copy
> | constructors? If so, we could have conditional compilation to exclude
> | those. Something like:
> |
> |   #ifndef FORCE_EXPLICIT
> |   IntegerMatrix(double*){...}
> |   #endif
> |
> | Then programmers who don't like surprises would define FORCE_EXPLICIT,
> | and then their code would sometimes not compile and they would have to
> | write an explicit conversion.
> |
> | (I've not thought that through, I just wanted to demonstrate what I had
> | in mind.)
>
> If you feel really strongly about you could consider a patch that makes this
> non-R behaviour you suggest an option.  To most of us who use Rcpp between R
> and C++ it really is a feature.
>
> Don't get me wrong though: I like your input here and maybe the implicit
> nature of things needs to be stressed even more.

The distinction between a C++ object that allocates its own storage
and one that uses the storage allocated by R is explicit in RcppEigen.
 The templated class Eigen::Map uses the storage from the SEXP and
throws an error if, for example, you pass integers to a double
precision vector.  In the RcppEigen-Intro vignette that Dirk and I are
writing we mention that, because of this, you really want to declare
such objects as const.

The vector structure for double precision values in Eigen is called VectorXd so

const  Eigen::Map<Eigen::VectorXd>   foo(as<Eigen::Map<Eigen::VectorXd> >(Foo));

is guaranteed to use R's storage for the vector or throw an error.

The topic of this thread, modifying an array in R memory from C++, is
a no-no.  There are occasions, such as optimizing models with complex
structures or MCMC, where you want to modify the state of the object
without copying a large structure every time but, in these cases, it
is better to keep the volatile storage in the C++ object and expose it
through methods and fields in a reference class object in R.  Rcpp
modules are one way of doing this.  I ended up rolling my own method
in the lme4Eigen package (only available on R-forge at present)
because of the need to allow for serialize/unserialize operations on
the reference class object.

> | > If you pass a matrix of ints to the NumericVector ctor, Rcpp has no
> | > choice but to coerce the data to a matrix of double, which means new
> | > data, hence the original data does not get modified.
> | >
> | > If you pass a matrix of double, no copy is required, therefore Rcpp
> | > operates directly on the data.
> | >
> | > Those are features.
> | >
> | >
> | >
> | > Le 4 nov. 2011 à 08:01, Darren Cook <darren at dcook.org> a écrit :
> | >
> | >>> I.e. the point of his code was to show that a matrix of doubles
> | >>> gets modified, a matrix of ints does not.
> | >>
> | >> Or change the first line from NumericMatrix to: Rcpp::IntegerMatrix
> | >> r_m(mem);
> | >>
> | >> Then the behaviour is reversed. The matrix of doubles does not get
> | >> modified, but the matrix of ints does!
> | >>
> | >> Dirk, Romain, this is a bug-in-waiting. Is there any way to
> | >> generate a warning when the implicit deep copy happens? Or
> | >> alternatively when the pointer is being used implicitly... but my
> | >> hunch is that I want to know when there is any implicit conversion
> | >> between int and double: modern C++ style is to explicitly declare
> | >> all type conversions with static_cast<> and friends.
> |
> |
> | --
> | Darren Cook, Software Researcher/Developer
> |
> | http://dcook.org/work/ (About me and my work)
> | http://dcook.org/blogs.html (My blogs and articles)
> | _______________________________________________
> | Rcpp-devel mailing list
> | Rcpp-devel at lists.r-forge.r-project.org
> | https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel
> --
> "Outside of a dog, a book is a man's best friend. Inside of a dog, it is too
> dark to read." -- Groucho Marx
> _______________________________________________
> Rcpp-devel mailing list
> Rcpp-devel at lists.r-forge.r-project.org
> https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel
>


More information about the Rcpp-devel mailing list