[Rcpp-devel] How to Get Pointer of Underlying Object of Rcpp Module Class
Tianqi Chen
tianqi.tchen at gmail.com
Wed Oct 7 08:15:56 CEST 2015
Thanks to Wush Wu. I think I now find the answer to the question by
using RCPP_EXPOSED_CLASS_NODECL
One note is that I have to use Rcpp::internal::make_new_object to create
the S4 object, instead of Rcpp::wrap. Because current wrap do
copy-construct from an existing object to a new pointer.
While in my case, doing so will trigger the destructor of the class to free
the arrays, and a explicit copy is needed .
So what I did is return a Rcpp::internal::make_new_object(new MyClass());
Which works for my case. But it sounds a bit undesirable as the function is
marked as internal.
Any suggestions?
Tianqi
On Tue, Oct 6, 2015 at 6:51 PM, Tianqi Chen <tianqi.tchen at gmail.com> wrote:
> Oh, the question is not about supporting native Save/Load from R. I
> understand the hardness of that due to no customized loader from external
> pointer. The function listed here aims to write a customized function like
> ```save.list``` instead of R's native save/load, which is doable. The
> question is how to get the underlying external ptr from an Rcpp
> class_<MyClass> Object, within the life cycle of the R session. Sorry about
> the confusion.
>
> Let me rephrase the question in this way: I want to implement a
> customized element-wise sum of a List of GPUArray object, which I exposed
> using Rcpp Module class. However, in order to do that, I need to somehow
> get the external Pointer of GPUArray from the S4 object, to redirect the
> call to InternalSumOnGPU function.
>
> After the computation, we need to wrap(construct) a new GPUArray S4 object
> from C++ side(what was normally provided was constructor from R side).
>
> ```
> class GPUArray {
> public:
> static SEXP Sum(SEXP list) {
> Rcpp::List data_lst(list);
> std::vector<GPUArray *> internals(data_lst[i]);
> for (size_t i = 0; i < data_lst.size(); ++i) {
> SEXP obj = data_lst[i];
> // Need to Get internal pointers from S4 GPUArray object
> internals[i] = GetPtr<GPUArray>(obj);
> }
> GPUArray *ret = InternalSumOnGPU(internals);
> // need to return the S4 object
> return class_<GPUArray>(ret);
> }
>
> };
>
> RCPP_MODULE(GPUArray) {
> class_<GPUArray>("GPUArray");
>
> function("gpu.sum", &GPUArray::Sum);
> }
> ```
>
>
> Tianqi
>
> On Tue, Oct 6, 2015 at 5:55 PM, Dirk Eddelbuettel <edd at debian.org> wrote:
>
>>
>> On 6 October 2015 at 14:40, Tianqi Chen wrote:
>> | Dear Rcpp Developers:
>> |
>> | ```c++
>> | class MyClass {
>> | public:
>> | static void SaveList(SEXP list, const std::string& filename) {
>> | Rcpp::List data_lst(list);
>> | std::vector<MyClass *> internals(data_lst[i]);
>> | for (size_t i = 0; i < data_lst.size(); ++i) {
>> | SEXP obj = data_lst[i];
>> | // Need to Get internal pointers from S4 MyClass object
>> | internals[i] = GetPtr<MyClass>(obj);
>> | }
>> | SomeRealSave(internals, filename);
>> | }
>> | static void LoadList(const std::string& filename) {
>> | std::vector<MyClass > internals;
>> | SomeReadLoad(&internals);
>> | Rcpp::List out(internals.size());
>> | for (size_t i = 0; i < internals.size(); ++i) {
>> | // need to construct a MyClass object from C++ side
>> | out[i] = MyClassConstructor(internals[i]);
>> | }
>> | return out;
>> | }
>> | };
>> |
>> | RCPP_MODULE(MyClass) {
>> | class_<MyClass>("MyClass");
>> |
>> | function("save.myclass.list", &MyClass::SaveList);
>> | function("load.myclass.list", &MyClass::LoadList);
>> | }
>> | ```
>> |
>> | To be specific, We have ways to Save/Load the pointers to the MyClass
>> object
>> | (in the SomeRealSave and SomeRealLoad). In our specific use-case, It
>> was an
>> | Array on GPU.
>>
>> As I recall, we had several discussions here a few years ago about the
>> impossibility of serialising Module objects to disk. In short, you
>> can't. You write out a bunch of ram which you can re-read, but that
>> doesn't
>> make an object.
>>
>> You will have to rebuild the objects at the next run time so that memory
>> is
>> allocated and correctly pointed to.
>>
>> See here for one such prior email:
>>
>> http://lists.r-forge.r-project.org/pipermail/rcpp-devel/2014-May/007539.html
>>
>> and an older one
>>
>> http://lists.r-forge.r-project.org/pipermail/rcpp-devel/2011-April/002107.html
>>
>> | So the question is how is there any solution to GetPtr<MyClass> and
>> | MyClassConstructor, so we can get the internal pointer of MyClass from
>> SEXP
>> | (which is the S4 object), and construct the corresponding S4 object
>> given the
>> | information of MyClass.
>> |
>> | What was wanted is indeed possible if we choose to only expose
>> XPtr<MyClass>,
>> | so we can simply do
>> | ```
>> | MyClass * GetPtr<MyClass>(SEXP obj) {
>> | XPtr<MyClass>(obj).get();
>> | }
>> | MyClassConstructor(MyClass *ptr) {
>> | return XPtr<MyClass>(ptr);
>> | }
>> |
>> | ```
>> |
>> | But it would be really nice we can directly return a wrapped S4 object
>> instead
>> | of raw ptr
>>
>> Yes, it would be -- but that doesn't meam it is possible under the current
>> framework.
>>
>> Sorry, Dirk
>>
>> --
>> http://dirk.eddelbuettel.com | @eddelbuettel | edd at debian.org
>>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.r-forge.r-project.org/pipermail/rcpp-devel/attachments/20151006/ab540a3d/attachment-0001.html>
More information about the Rcpp-devel
mailing list