
// for CUDA or OMP backend

// interface to Thrust sort from R

// compile as follows (adjusting paths as needed; run R CMD SHLIB on
// sd.c or similar to see paths)):

// CUDA backend:

//    nvcc -c SortForR.cpp -x cu
//    nvcc -shared -Xlinker "-L/usr/lib/R/lib -lR" -L/usr/local/cuda/lib
//       SortForR.o -o SortForR.so

// OMP backend (64-bit):

// g++ -I/usr/share/R/include -fpic -g -O2 -c SortForR.cpp -o SortForR.o
//    -fopenmp -lgomp -DTHRUST_DEVICE_BACKEND=THRUST_DEVICE_BACKEND_OMP
//    -I/home/matloff/Thrust
// g++ -shared -o SortForR.so SortForR.o -L/usr/lib64/R/lib -lR -lgomp

// you can also set environment flags and then build using R; e.g.
// replace the 2 g++ cmds above by

/* 
setenv PKG_CPPFLAGS "-I/home/matloff/Thrust -fopenmp -DTHRUST_DEVICE_BACKEND=THRUST_DEVICE_BACKEND_OMP -g"
setenv PKG_LIBS "-lgomp"
R CMD SHLIB SortForR.cpp
*/

// in the CUDA case:

/*
nvcc -c SortForR.cpp -x cu
setenv PKG_LIBS "-L/usr/local/cuda/lib -lcudart"
R CMD SHLIB SortForR.o
*/

// load and test:
/*
dyn.load("SortForR.so")
x <- sample(1:25,8)
.C("tsort",as.double(x),as.integer(8),xout=double(8))
*/

// definitely needed
extern "C" void tsort(double *x, int *nx, double *xout);

// #include <R.h>

#include <thrust/host_vector.h>
#include <thrust/device_vector.h>
#include <thrust/sort.h>

void tsort(double *x, int *nx, double *xout) 
{  int n = *nx;
   // set up device vector and copy x to it
   thrust::device_vector<double> dx(x,x+n);
   // sort, then copy back to x
   thrust::sort(dx.begin(), dx.end());
   thrust::copy(dx.begin(), dx.end(),xout);
}

