#ifndef GPU_DIFFNB
#define GPU_DIFFNB
template <typename T>
static __device__ inline bool d_DIFFNB(int& csize, byte in [CS], byte out [CS], byte temp [CS])
{
const T s = (T)0xAAAAAAAAAAAAAAAAULL;
T* const in_t = (T*)in;
T* const out_t = (T*)out;
const int size = csize / sizeof(T); const int tid = threadIdx.x;
for (int i = tid; i < size; i += TPB) {
const T prev = (i == 0) ? 0 : in_t[i - 1];
const T val = in_t[i];
const T data = val - prev;
out_t[i] = (data + s) ^ s;
}
if constexpr (sizeof(T) > 1) {
const int extra = csize % sizeof(T);
if (tid < extra) out[csize - extra + tid] = in[csize - extra + tid];
}
return true;
}
template <typename T>
static __device__ inline void d_iDIFFNB(int& csize, byte in [CS], byte out [CS], byte temp [CS])
{
const T s = (T)0xAAAAAAAAAAAAAAAAULL;
T* const in_t = (T*)in;
T* const out_t = (T*)out;
const int size = csize / sizeof(T); const int tid = threadIdx.x;
const int beg = tid * size / TPB;
const int end = (tid + 1) * size / TPB;
T sum = 0;
for (int i = beg; i < end; i++) {
const T data = in_t[i];
const T val = (data ^ s) - s;
sum += val;
in_t[i] = val;
}
sum = block_prefix_sum(sum, temp);
for (int i = end - 1; i >= beg; i--) {
out_t[i] = sum;
sum -= in_t[i];
}
if constexpr (sizeof(T) > 1) {
const int extra = csize % sizeof(T);
if (tid < extra) out[csize - extra + tid] = in[csize - extra + tid];
}
}
#endif