#ifndef GPU_DIFFMS
#define GPU_DIFFMS
template <typename T>
static __device__ inline bool d_DIFFMS(int& csize, byte in [CS], byte out [CS], byte temp [CS])
{
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 << 1) ^ ((std::make_signed_t<T>)data) >> (sizeof(T) * 8 - 1);
}
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_iDIFFMS(int& csize, byte in [CS], byte out [CS], byte temp [CS])
{
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 >> 1) ^ ((std::make_signed_t<T>)(data << (sizeof(T) * 8 - 1))) >> (sizeof(T) * 8 - 1);
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