Unexpected behavior when using macro to loop over vector

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

Unexpected behavior when using macro to loop over vector

Wang Jiefei
Hi all,

I found an unexpected behavior when I was trying to use the macro defined
in "R_ext/Itermacros.h"  to loop over an atomic vector. Here is a minimum
example:

C++ code
```
#include "R_ext/Itermacros.h"
#define GET_REGION_BUFSIZE 2
//Redefine the macro since C++ is not happy with the implicit type
conversion
#define ITERATE_BY_REGION_PARTIAL(sx, px, idx, nb, etype, vtype, \
 strt, nfull, expr) do { \
const etype *px = (etype*)DATAPTR_OR_NULL(sx); \
if (px != NULL) { \
   R_xlen_t __ibr_n__ = strt + nfull; \
   R_xlen_t nb = __ibr_n__; \
   for (R_xlen_t idx = strt; idx < __ibr_n__; idx += nb) { \
expr \
    } \
} \
else ITERATE_BY_REGION_PARTIAL0(sx, px, idx, nb, etype, vtype, \
strt, nfull, expr); \
    } while (0)
// [[Rcpp::export]]
void C_testPrint(SEXP x) {
ITERATE_BY_REGION_PARTIAL(x, ptr, idx, nbatch, double, REAL, 1, 4, {
for (R_xlen_t i = 0; i < nbatch; i++)
Rprintf("idx: %lld, i: %lld, ptr:%f\n", idx, i, ptr[i]);
});
}
```

The function C_testPrint loops over its argument x and prints out one value
of x at each loop. The loop starts from the second element and ends in the
fifth element of x. I also redefine the buffer size to see the effect of
it. Here is my R code:

R code
```
> C_testPrint(as.numeric(1:10))
idx: 1, i: 0, ptr:2.000000
idx: 1, i: 1, ptr:3.000000
idx: 3, i: 0, ptr:4.000000
idx: 3, i: 1, ptr:5.000000
> C_testPrint(c(1,2,3,4,5,6,7,8,9,10))
idx: 1, i: 0, ptr:1.000000
idx: 1, i: 1, ptr:2.000000
idx: 1, i: 2, ptr:3.000000
idx: 1, i: 3, ptr:4.000000
idx: 1, i: 4, ptr:5.000000
```

There are two problems in the outputs:
1. The numbers of lines are different
2. The starting indices are not the same.

From my understanding, the first output seems correct to me. The second is
not unexpected. I believe the differences are due to the accessibility of
the data pointer. Did I misunderstand and misuse the macro? Or is it a bug
in R? Here is my session info. My R is a bit outdated but the macro seems
unchanged in R 4.0. Thanks

```
> sessionInfo()
R Under development (unstable) (2019-08-22 r77060)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows >= 8 x64 (build 9200)
```

        [[alternative HTML version deleted]]

______________________________________________
[hidden email] mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel
Reply | Threaded
Open this post in threaded view
|

Re: Unexpected behavior when using macro to loop over vector

Tomas Kalibera
On 10/23/19 6:45 AM, Wang Jiefei wrote:

> Hi all,
>
> I found an unexpected behavior when I was trying to use the macro defined
> in "R_ext/Itermacros.h"  to loop over an atomic vector. Here is a minimum
> example:
>
> C++ code
> ```
> #include "R_ext/Itermacros.h"
> #define GET_REGION_BUFSIZE 2
> //Redefine the macro since C++ is not happy with the implicit type
> conversion
> #define ITERATE_BY_REGION_PARTIAL(sx, px, idx, nb, etype, vtype, \
>   strt, nfull, expr) do { \
> const etype *px = (etype*)DATAPTR_OR_NULL(sx); \
> if (px != NULL) { \
>     R_xlen_t __ibr_n__ = strt + nfull; \
>     R_xlen_t nb = __ibr_n__; \
>     for (R_xlen_t idx = strt; idx < __ibr_n__; idx += nb) { \
> expr \
>      } \
> } \
> else ITERATE_BY_REGION_PARTIAL0(sx, px, idx, nb, etype, vtype, \
> strt, nfull, expr); \
>      } while (0)
> // [[Rcpp::export]]
> void C_testPrint(SEXP x) {
> ITERATE_BY_REGION_PARTIAL(x, ptr, idx, nbatch, double, REAL, 1, 4, {
> for (R_xlen_t i = 0; i < nbatch; i++)
> Rprintf("idx: %lld, i: %lld, ptr:%f\n", idx, i, ptr[i]);

You need to index "ptr" by "idx + i", not by "i". Have a look at how the
macros are used in R, e.g. printvector.c.

Best,
Tomas

> });
> }
> ```
>
> The function C_testPrint loops over its argument x and prints out one value
> of x at each loop. The loop starts from the second element and ends in the
> fifth element of x. I also redefine the buffer size to see the effect of
> it. Here is my R code:
>
> R code
> ```
>> C_testPrint(as.numeric(1:10))
> idx: 1, i: 0, ptr:2.000000
> idx: 1, i: 1, ptr:3.000000
> idx: 3, i: 0, ptr:4.000000
> idx: 3, i: 1, ptr:5.000000
>> C_testPrint(c(1,2,3,4,5,6,7,8,9,10))
> idx: 1, i: 0, ptr:1.000000
> idx: 1, i: 1, ptr:2.000000
> idx: 1, i: 2, ptr:3.000000
> idx: 1, i: 3, ptr:4.000000
> idx: 1, i: 4, ptr:5.000000
> ```
>
> There are two problems in the outputs:
> 1. The numbers of lines are different
> 2. The starting indices are not the same.
>
>  From my understanding, the first output seems correct to me. The second is
> not unexpected. I believe the differences are due to the accessibility of
> the data pointer. Did I misunderstand and misuse the macro? Or is it a bug
> in R? Here is my session info. My R is a bit outdated but the macro seems
> unchanged in R 4.0. Thanks
>
> ```
>> sessionInfo()
> R Under development (unstable) (2019-08-22 r77060)
> Platform: x86_64-w64-mingw32/x64 (64-bit)
> Running under: Windows >= 8 x64 (build 9200)
> ```
>
> [[alternative HTML version deleted]]
>
> ______________________________________________
> [hidden email] mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel

______________________________________________
[hidden email] mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel
Reply | Threaded
Open this post in threaded view
|

Re: Unexpected behavior when using macro to loop over vector

Tomas Kalibera
On 10/25/19 11:01 AM, Tomas Kalibera wrote:

> On 10/23/19 6:45 AM, Wang Jiefei wrote:
>> Hi all,
>>
>> I found an unexpected behavior when I was trying to use the macro
>> defined
>> in "R_ext/Itermacros.h"  to loop over an atomic vector. Here is a
>> minimum
>> example:
>>
>> C++ code
>> ```
>> #include "R_ext/Itermacros.h"
>> #define GET_REGION_BUFSIZE 2
>> //Redefine the macro since C++ is not happy with the implicit type
>> conversion
>> #define ITERATE_BY_REGION_PARTIAL(sx, px, idx, nb, etype, vtype, \
>>   strt, nfull, expr) do { \
>> const etype *px = (etype*)DATAPTR_OR_NULL(sx); \
>> if (px != NULL) { \
>>     R_xlen_t __ibr_n__ = strt + nfull; \
>>     R_xlen_t nb = __ibr_n__; \
>>     for (R_xlen_t idx = strt; idx < __ibr_n__; idx += nb) { \
>> expr \
>>      } \
>> } \
>> else ITERATE_BY_REGION_PARTIAL0(sx, px, idx, nb, etype, vtype, \
>> strt, nfull, expr); \
>>      } while (0)
>> // [[Rcpp::export]]
>> void C_testPrint(SEXP x) {
>> ITERATE_BY_REGION_PARTIAL(x, ptr, idx, nbatch, double, REAL, 1, 4, {
>> for (R_xlen_t i = 0; i < nbatch; i++)
>> Rprintf("idx: %lld, i: %lld, ptr:%f\n", idx, i, ptr[i]);
>
> You need to index "ptr" by "idx + i", not by "i". Have a look at how
> the macros are used in R, e.g. printvector.c.

Actually, the macro should do this for you, we will investigate/fix.
Thanks for the report!

Best
Tomas

>
> Best,
> Tomas
>
>> });
>> }
>> ```
>>
>> The function C_testPrint loops over its argument x and prints out one
>> value
>> of x at each loop. The loop starts from the second element and ends
>> in the
>> fifth element of x. I also redefine the buffer size to see the effect of
>> it. Here is my R code:
>>
>> R code
>> ```
>>> C_testPrint(as.numeric(1:10))
>> idx: 1, i: 0, ptr:2.000000
>> idx: 1, i: 1, ptr:3.000000
>> idx: 3, i: 0, ptr:4.000000
>> idx: 3, i: 1, ptr:5.000000
>>> C_testPrint(c(1,2,3,4,5,6,7,8,9,10))
>> idx: 1, i: 0, ptr:1.000000
>> idx: 1, i: 1, ptr:2.000000
>> idx: 1, i: 2, ptr:3.000000
>> idx: 1, i: 3, ptr:4.000000
>> idx: 1, i: 4, ptr:5.000000
>> ```
>>
>> There are two problems in the outputs:
>> 1. The numbers of lines are different
>> 2. The starting indices are not the same.
>>
>>  From my understanding, the first output seems correct to me. The
>> second is
>> not unexpected. I believe the differences are due to the
>> accessibility of
>> the data pointer. Did I misunderstand and misuse the macro? Or is it
>> a bug
>> in R? Here is my session info. My R is a bit outdated but the macro
>> seems
>> unchanged in R 4.0. Thanks
>>
>> ```
>>> sessionInfo()
>> R Under development (unstable) (2019-08-22 r77060)
>> Platform: x86_64-w64-mingw32/x64 (64-bit)
>> Running under: Windows >= 8 x64 (build 9200)
>> ```
>>
>>     [[alternative HTML version deleted]]
>>
>> ______________________________________________
>> [hidden email] mailing list
>> https://stat.ethz.ch/mailman/listinfo/r-devel
>
>

______________________________________________
[hidden email] mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel
Reply | Threaded
Open this post in threaded view
|

Re: Unexpected behavior when using macro to loop over vector

Wang Jiefei
Thank you, Tomas. I appreciate your help. BTW, could you also add an
explicit type conversion in " ITERATE_BY_REGION_PARTIAL" macro while you
are fixing the bug? C++ compiler does not happy with the implicit
conversion from void* to T* somehow and I have to redefine it before using
the macro.

Best,
Jiefei

On Fri, Oct 25, 2019 at 11:13 AM Tomas Kalibera <[hidden email]>
wrote:

> On 10/25/19 11:01 AM, Tomas Kalibera wrote:
> > On 10/23/19 6:45 AM, Wang Jiefei wrote:
> >> Hi all,
> >>
> >> I found an unexpected behavior when I was trying to use the macro
> >> defined
> >> in "R_ext/Itermacros.h"  to loop over an atomic vector. Here is a
> >> minimum
> >> example:
> >>
> >> C++ code
> >> ```
> >> #include "R_ext/Itermacros.h"
> >> #define GET_REGION_BUFSIZE 2
> >> //Redefine the macro since C++ is not happy with the implicit type
> >> conversion
> >> #define ITERATE_BY_REGION_PARTIAL(sx, px, idx, nb, etype, vtype, \
> >>   strt, nfull, expr) do { \
> >> const etype *px = (etype*)DATAPTR_OR_NULL(sx); \
> >> if (px != NULL) { \
> >>     R_xlen_t __ibr_n__ = strt + nfull; \
> >>     R_xlen_t nb = __ibr_n__; \
> >>     for (R_xlen_t idx = strt; idx < __ibr_n__; idx += nb) { \
> >> expr \
> >>      } \
> >> } \
> >> else ITERATE_BY_REGION_PARTIAL0(sx, px, idx, nb, etype, vtype, \
> >> strt, nfull, expr); \
> >>      } while (0)
> >> // [[Rcpp::export]]
> >> void C_testPrint(SEXP x) {
> >> ITERATE_BY_REGION_PARTIAL(x, ptr, idx, nbatch, double, REAL, 1, 4, {
> >> for (R_xlen_t i = 0; i < nbatch; i++)
> >> Rprintf("idx: %lld, i: %lld, ptr:%f\n", idx, i, ptr[i]);
> >
> > You need to index "ptr" by "idx + i", not by "i". Have a look at how
> > the macros are used in R, e.g. printvector.c.
>
> Actually, the macro should do this for you, we will investigate/fix.
> Thanks for the report!
>
> Best
> Tomas
>
> >
> > Best,
> > Tomas
> >
> >> });
> >> }
> >> ```
> >>
> >> The function C_testPrint loops over its argument x and prints out one
> >> value
> >> of x at each loop. The loop starts from the second element and ends
> >> in the
> >> fifth element of x. I also redefine the buffer size to see the effect of
> >> it. Here is my R code:
> >>
> >> R code
> >> ```
> >>> C_testPrint(as.numeric(1:10))
> >> idx: 1, i: 0, ptr:2.000000
> >> idx: 1, i: 1, ptr:3.000000
> >> idx: 3, i: 0, ptr:4.000000
> >> idx: 3, i: 1, ptr:5.000000
> >>> C_testPrint(c(1,2,3,4,5,6,7,8,9,10))
> >> idx: 1, i: 0, ptr:1.000000
> >> idx: 1, i: 1, ptr:2.000000
> >> idx: 1, i: 2, ptr:3.000000
> >> idx: 1, i: 3, ptr:4.000000
> >> idx: 1, i: 4, ptr:5.000000
> >> ```
> >>
> >> There are two problems in the outputs:
> >> 1. The numbers of lines are different
> >> 2. The starting indices are not the same.
> >>
> >>  From my understanding, the first output seems correct to me. The
> >> second is
> >> not unexpected. I believe the differences are due to the
> >> accessibility of
> >> the data pointer. Did I misunderstand and misuse the macro? Or is it
> >> a bug
> >> in R? Here is my session info. My R is a bit outdated but the macro
> >> seems
> >> unchanged in R 4.0. Thanks
> >>
> >> ```
> >>> sessionInfo()
> >> R Under development (unstable) (2019-08-22 r77060)
> >> Platform: x86_64-w64-mingw32/x64 (64-bit)
> >> Running under: Windows >= 8 x64 (build 9200)
> >> ```
> >>
> >>     [[alternative HTML version deleted]]
> >>
> >> ______________________________________________
> >> [hidden email] mailing list
> >> https://stat.ethz.ch/mailman/listinfo/r-devel
> >
> >
>
>

        [[alternative HTML version deleted]]

______________________________________________
[hidden email] mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel
Reply | Threaded
Open this post in threaded view
|

Re: Unexpected behavior when using macro to loop over vector

Tomas Kalibera
On 10/25/19 5:20 PM, Wang Jiefei wrote:
> Thank you, Tomas. I appreciate your help. BTW, could you also add an
> explicit type conversion in " ITERATE_BY_REGION_PARTIAL" macro while
> you are fixing the bug? C++ compiler does not happy with the implicit
> conversion from void* to T* somehow and I have to redefine it before
> using the macro.

Yes, C++ requires a cast from void to non-void pointer. Fixed now in
R-devel (77331): your example iterator should now work also for the
non-compact sequence.

Best
Tomas

>
> Best,
> Jiefei
>
> On Fri, Oct 25, 2019 at 11:13 AM Tomas Kalibera
> <[hidden email] <mailto:[hidden email]>> wrote:
>
>     On 10/25/19 11:01 AM, Tomas Kalibera wrote:
>     > On 10/23/19 6:45 AM, Wang Jiefei wrote:
>     >> Hi all,
>     >>
>     >> I found an unexpected behavior when I was trying to use the macro
>     >> defined
>     >> in "R_ext/Itermacros.h"  to loop over an atomic vector. Here is a
>     >> minimum
>     >> example:
>     >>
>     >> C++ code
>     >> ```
>     >> #include "R_ext/Itermacros.h"
>     >> #define GET_REGION_BUFSIZE 2
>     >> //Redefine the macro since C++ is not happy with the implicit type
>     >> conversion
>     >> #define ITERATE_BY_REGION_PARTIAL(sx, px, idx, nb, etype, vtype, \
>     >>   strt, nfull, expr) do { \
>     >> const etype *px = (etype*)DATAPTR_OR_NULL(sx); \
>     >> if (px != NULL) { \
>     >>     R_xlen_t __ibr_n__ = strt + nfull; \
>     >>     R_xlen_t nb = __ibr_n__; \
>     >>     for (R_xlen_t idx = strt; idx < __ibr_n__; idx += nb) { \
>     >> expr \
>     >>      } \
>     >> } \
>     >> else ITERATE_BY_REGION_PARTIAL0(sx, px, idx, nb, etype, vtype, \
>     >> strt, nfull, expr); \
>     >>      } while (0)
>     >> // [[Rcpp::export]]
>     >> void C_testPrint(SEXP x) {
>     >> ITERATE_BY_REGION_PARTIAL(x, ptr, idx, nbatch, double, REAL, 1,
>     4, {
>     >> for (R_xlen_t i = 0; i < nbatch; i++)
>     >> Rprintf("idx: %lld, i: %lld, ptr:%f\n", idx, i, ptr[i]);
>     >
>     > You need to index "ptr" by "idx + i", not by "i". Have a look at
>     how
>     > the macros are used in R, e.g. printvector.c.
>
>     Actually, the macro should do this for you, we will investigate/fix.
>     Thanks for the report!
>
>     Best
>     Tomas
>
>     >
>     > Best,
>     > Tomas
>     >
>     >> });
>     >> }
>     >> ```
>     >>
>     >> The function C_testPrint loops over its argument x and prints
>     out one
>     >> value
>     >> of x at each loop. The loop starts from the second element and
>     ends
>     >> in the
>     >> fifth element of x. I also redefine the buffer size to see the
>     effect of
>     >> it. Here is my R code:
>     >>
>     >> R code
>     >> ```
>     >>> C_testPrint(as.numeric(1:10))
>     >> idx: 1, i: 0, ptr:2.000000
>     >> idx: 1, i: 1, ptr:3.000000
>     >> idx: 3, i: 0, ptr:4.000000
>     >> idx: 3, i: 1, ptr:5.000000
>     >>> C_testPrint(c(1,2,3,4,5,6,7,8,9,10))
>     >> idx: 1, i: 0, ptr:1.000000
>     >> idx: 1, i: 1, ptr:2.000000
>     >> idx: 1, i: 2, ptr:3.000000
>     >> idx: 1, i: 3, ptr:4.000000
>     >> idx: 1, i: 4, ptr:5.000000
>     >> ```
>     >>
>     >> There are two problems in the outputs:
>     >> 1. The numbers of lines are different
>     >> 2. The starting indices are not the same.
>     >>
>     >>  From my understanding, the first output seems correct to me. The
>     >> second is
>     >> not unexpected. I believe the differences are due to the
>     >> accessibility of
>     >> the data pointer. Did I misunderstand and misuse the macro? Or
>     is it
>     >> a bug
>     >> in R? Here is my session info. My R is a bit outdated but the
>     macro
>     >> seems
>     >> unchanged in R 4.0. Thanks
>     >>
>     >> ```
>     >>> sessionInfo()
>     >> R Under development (unstable) (2019-08-22 r77060)
>     >> Platform: x86_64-w64-mingw32/x64 (64-bit)
>     >> Running under: Windows >= 8 x64 (build 9200)
>     >> ```
>     >>
>     >>     [[alternative HTML version deleted]]
>     >>
>     >> ______________________________________________
>     >> [hidden email] <mailto:[hidden email]> mailing list
>     >> https://stat.ethz.ch/mailman/listinfo/r-devel
>     >
>     >
>


        [[alternative HTML version deleted]]

______________________________________________
[hidden email] mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel