From @zwj|08 @end|ng |rom gm@||@com  Thu May 16 20:57:17 2019
From: @zwj|08 @end|ng |rom gm@||@com (=?UTF-8?B?5LuL6Z2e546L?=)
Date: Thu, 16 May 2019 14:57:17 -0400
Subject: [Rd] ALTREP: Bug reports
Message-ID: <CAGiFhPPjds+myJWKxfCBC_f3L+kSofnm+g3q73ntZ6v6=aATcg@mail.gmail.com>

Hello,

I have encountered two bugs when using ALTREP APIs.

1. STDVEC_DATAPTR

>From RInternal.h file it has a comment:

/* ALTREP support */
> void *(STDVEC_DATAPTR)(SEXP x);


However, this comment might not be true, the easiest way to verify it is to
define a C++ function:

 void C_testFunc(SEXP a)
> {
> STDVEC_DATAPTR(a);
> }


and call it in R via

> a=1:10
> > C_testFunc(a)
> Error in C_testFunc(a) : cannot get STDVEC_DATAPTR from ALTREP object


 We can inspect the internal type and call ALTREP function to check if it
is an ALTREP:

> .Internal(inspect(a))
> @0x000000001b5a3310 13 INTSXP g0c0 [NAM(7)]  1 : 10 (compact)
> > #This is a wrapper of ALTREP
> > is.altrep(a)
> [1] TRUE


I've also defined an ALTREP type and it did not work either. I guess this
might be a bug? Or did I miss something?

2. Wrapper objects in ALTREP

If the duplicate function is defined to return the object itself:

SEXP vector_dulplicate(SEXP x, Rboolean deep) {
return(x);
}

In R an ALTREP object will behave like an environment (pass-by-reference).
However, if we do something like(pseudo code):

n=100
> x=runif(n)
> alt1=createAltrep(x)
> alt2=alt1
> alt2[1]=10
> .Internal(inspect(alt1))
> .Internal(inspect(alt2))


The result would be:

> .Internal(inspect(alt1))
> @0x00000000156f4d18 14 REALSXP g0c0 [NAM(7)]
> > .Internal(inspect(alt2 ))
> @0x00000000156a33e0 14 REALSXP g0c0 [NAM(7)]  wrapper
> [srt=-2147483648,no_na=0]
>   @0x00000000156f4d18 14 REALSXP g0c0 [NAM(7)]


It seems like the object alt2 automatically gets wrapped by R. Although at
the R level it seems fine because there are no differences between alt1 and
alt2, if we define a C function as:

SEXP C_peekSharedMemory(SEXP x) {
> return(R_altrep_data1(x));

}


and call it in R to get the internal data structure of an ALTREP object.

C_peekSharedMemory(alt1)
> C_peekSharedMemory(alt2)


The first one correctly returns its internal data structure, but the second
one returns the ALTREP object it wraps since the wrapper itself is an
ALTREP. This behavior is unexpected. Since the dulplicate function returns
the object itself, I will expect alt1 and alt2 should be the same object.
Even if they are essentially not the same, calling the same function should
at least return the same result. Other than that, It seems like R does not
always wrap an ALTREP object. If we change n from 100 to 10 and check the
internal again, alt2 will not get wrapped. This makes the problem even more
difficult since we cannot predict when would the wrapper appear.

Here is the source code for the wrapper:
https://github.com/wch/r-source/blob/trunk/src/main/altclasses.c#L1399

Here is a working example if one can build the sharedObject package from
https://github.com/Jiefei-Wang/sharedObject

n=100
> x=runif(n)
> so1=sharedObject(x,copyOnWrite = FALSE)
> so2=so1
> so2[1]=10
> .Internal(inspect(so1))
> .Internal(inspect(so2))


Here is my session info:

R version 3.6.0 alpha (2019-04-08 r76348)
> Platform: x86_64-w64-mingw32/x64 (64-bit)
> Running under: Windows >= 8 x64 (build 9200)
> Matrix products: default
> locale:
> [1] LC_COLLATE=English_United States.1252  LC_CTYPE=English_United
> States.1252
> [3] LC_MONETARY=English_United States.1252 LC_NUMERIC=C
>
> [5] LC_TIME=English_United States.1252
> attached base packages:
> [1] stats     graphics  grDevices utils     datasets  methods   base
> other attached packages:
> [1] sharedObject_0.0.99
> loaded via a namespace (and not attached):
> [1] compiler_3.6.0 tools_3.6.0    Rcpp_1.0.1


Best,
Jiefei

	[[alternative HTML version deleted]]



[Rd] ALTREP: Bug reports
=?UTF-8?B?5LuL6Z2e546L?=