xtensor-r icon indicating copy to clipboard operation
xtensor-r copied to clipboard

Crash with `argsort()` on an `rarray` but not a column major `xarray`

Open DavisVaughan opened this issue 5 years ago • 2 comments

For some reason, calling argsort() on an rarray like this one crashes, but works on a column major xarray.

// [[Rcpp::depends(xtensor)]]
// [[Rcpp::plugins(cpp14)]]

#include <xtensor-r/rarray.hpp>
#include <xtensor/xsort.hpp>
#include <xtensor/xio.hpp>
#include <Rcpp.h>
using namespace Rcpp;

// [[Rcpp::export]]
void argsort_test_xarray() {
  xt::xarray<int, xt::layout_type::column_major> x =
    {{{1, 2, 3}, {4, 5, 6}},
     {{7, 8, 9}, {10, 11, 12}}};

  std::cout << x << std::endl;

  auto x_sort = xt::argsort(x, 0);

  std::cout << x_sort << std::endl;
}

// [[Rcpp::export]]
void argsort_test_rarray() {
  xt::rarray<int> x =
    {{{1, 2, 3}, {4, 5, 6}},
     {{7, 8, 9}, {10, 11, 12}}};

  std::cout << x << std::endl;

  auto x_sort = xt::argsort(x, 0);

  std::cout << x_sort << std::endl;
}
> Rcpp::sourceCpp('~/Desktop/test.cpp')
> argsort_test_xarray()
{{{ 1,  2,  3},
  { 4,  5,  6}},
 {{ 7,  8,  9},
  {10, 11, 12}}}
{{{0, 0, 0},
  {0, 0, 0}},
 {{1, 1, 1},
  {1, 1, 1}}}

DavisVaughan avatar Apr 24 '19 12:04 DavisVaughan

Trying to convert it directly into a SEXP and return it is unstable. It returns sometimes, but occasionally locks up the R session or crashes it. So calling something like this occasionally crashes R:

// [[Rcpp::depends(xtensor)]]
// [[Rcpp::plugins(cpp14)]]

#include <xtensor-r/rarray.hpp>
#include <xtensor/xsort.hpp>
#include <xtensor/xio.hpp>
#include <Rcpp.h>
using namespace Rcpp;

// [[Rcpp::export]]
SEXP argsort_test_rarray() {
  xt::rarray<int> x =
    {{{1, 2, 3}, {4, 5, 6}},
     {{7, 8, 9}, {10, 11, 12}}};

  xt::rarray<int> x_sort = xt::argsort(x, 0);

  return x_sort;
}

DavisVaughan avatar Apr 24 '19 13:04 DavisVaughan

Going through the stack of: SEXP -> rarray -> xarray -> argsort -> rarray -> SEXP works but obviously it would be better if this was fixed.

i.e. all of these results look correct

// [[Rcpp::depends(xtensor)]]
// [[Rcpp::plugins(cpp14)]]

#include <xtensor-r/rarray.hpp>
#include <xtensor/xsort.hpp>
#include <xtensor/xio.hpp>
#include <Rcpp.h>
using namespace Rcpp;

// [[Rcpp::export]]
SEXP argsort_long_route(xt::rarray<int> x, std::ptrdiff_t axis) {
  
  // Go through xarray
  xt::xarray<int, xt::layout_type::column_major> x_xarray(x);
  
  // Call argsort() on the xarray
  xt::xarray<int, xt::layout_type::column_major> x_sort = xt::argsort(x_xarray, axis);
  
  // Back to an rarray
  xt::rarray<int> x_rarray(x_sort);
  
  return x_rarray;
}
Rcpp::sourceCpp("~/Desktop/test.cpp")

x <- array(c(1:6, 12:7), c(2,3,2))
x
#> , , 1
#> 
#>      [,1] [,2] [,3]
#> [1,]    1    3    5
#> [2,]    2    4    6
#> 
#> , , 2
#> 
#>      [,1] [,2] [,3]
#> [1,]   12   10    8
#> [2,]   11    9    7

argsort_long_route(x, 0)
#> , , 1
#> 
#>      [,1] [,2] [,3]
#> [1,]    0    0    0
#> [2,]    1    1    1
#> 
#> , , 2
#> 
#>      [,1] [,2] [,3]
#> [1,]    1    1    1
#> [2,]    0    0    0

argsort_long_route(x, 1)
#> , , 1
#> 
#>      [,1] [,2] [,3]
#> [1,]    0    1    2
#> [2,]    0    1    2
#> 
#> , , 2
#> 
#>      [,1] [,2] [,3]
#> [1,]    2    1    0
#> [2,]    2    1    0

argsort_long_route(x, 2)
#> , , 1
#> 
#>      [,1] [,2] [,3]
#> [1,]    0    0    0
#> [2,]    0    0    0
#> 
#> , , 2
#> 
#>      [,1] [,2] [,3]
#> [1,]    1    1    1
#> [2,]    1    1    1

Created on 2019-04-24 by the reprex package (v0.2.1.9000)

DavisVaughan avatar Apr 24 '19 13:04 DavisVaughan