blob: a14f59de0a7d14ebb59a6df2f21d2413d7629783 [file]
#ifndef TH_GENERIC_FILE
#define TH_GENERIC_FILE "TH/generic/THVectorDefault.cpp"
#else
#include <ATen/Context.h>
void THVector_(fill_DEFAULT)(scalar_t *x, const scalar_t c, const ptrdiff_t n) {
ptrdiff_t i = 0;
for(; i <n-4; i+=4)
{
x[i] = c;
x[i+1] = c;
x[i+2] = c;
x[i+3] = c;
}
for(; i < n; i++)
x[i] = c;
}
#if !defined(TH_REAL_IS_BOOL) /* non bool only part */
void THVector_(copy_DEFAULT)(scalar_t *x, const scalar_t *y, const ptrdiff_t n) {
ptrdiff_t i = 0;
for(; i <n-4; i+=4)
{
x[i] = y[i];
x[i+1] = y[i+1];
x[i+2] = y[i+2];
x[i+3] = y[i+3];
}
for(; i < n; i++)
x[i] = y[i];
}
void THVector_(cadd_DEFAULT)(scalar_t *z, const scalar_t *x, const scalar_t *y, const scalar_t c, const ptrdiff_t n)
{
ptrdiff_t i = 0;
for(; i<n-4; i+=4)
{
z[i] = x[i] + c * y[i];
z[i+1] = x[i+1] + c * y[i+1];
z[i+2] = x[i+2] + c * y[i+2];
z[i+3] = x[i+3] + c * y[i+3];
}
for(; i<n; i++)
z[i] = x[i] + c * y[i];
}
void THVector_(adds_DEFAULT)(scalar_t *y, const scalar_t *x, const scalar_t c, const ptrdiff_t n)
{
ptrdiff_t i = 0;
for(; i<n-4; i+=4)
{
y[i] = x[i] + c;
y[i+1] = x[i+1] + c;
y[i+2] = x[i+2] + c;
y[i+3] = x[i+3] + c;
}
for(; i<n; i++)
y[i] = x[i] + c;
}
void THVector_(cmul_DEFAULT)(scalar_t *z, const scalar_t *x, const scalar_t *y, const ptrdiff_t n)
{
ptrdiff_t i = 0;
for(; i <n-4; i+=4)
{
z[i] = x[i] * y[i];
z[i+1] = x[i+1] * y[i+1];
z[i+2] = x[i+2] * y[i+2];
z[i+3] = x[i+3] * y[i+3];
}
for(; i < n; i++)
z[i] = x[i] * y[i];
}
void THVector_(muls_DEFAULT)(scalar_t *y, const scalar_t *x, const scalar_t c, const ptrdiff_t n)
{
ptrdiff_t i = 0;
for(; i <n-4; i+=4)
{
y[i] = x[i] * c;
y[i+1] = x[i+1] * c;
y[i+2] = x[i+2] * c;
y[i+3] = x[i+3] * c;
}
for(; i < n; i++)
y[i] = x[i] * c;
}
void THVector_(cdiv_DEFAULT)(scalar_t *z, const scalar_t *x, const scalar_t *y, const ptrdiff_t n)
{
ptrdiff_t i = 0;
for(; i<n-4; i+=4)
{
z[i] = x[i] / y[i];
z[i+1] = x[i+1] / y[i+1];
z[i+2] = x[i+2] / y[i+2];
z[i+3] = x[i+3] / y[i+3];
}
for(; i < n; i++)
z[i] = x[i] / y[i];
}
void THVector_(divs_DEFAULT)(scalar_t *y, const scalar_t *x, const scalar_t c, const ptrdiff_t n)
{
ptrdiff_t i = 0;
for(; i<n-4; i+=4)
{
y[i] = x[i] / c;
y[i+1] = x[i+1] / c;
y[i+2] = x[i+2] / c;
y[i+3] = x[i+3] / c;
}
for(; i < n; i++)
y[i] = x[i] / c;
}
// Fills 16 normally distributed samples into data, interleaved with a
// stride of 8, i.e. in order of ([0], [8]), ([1], [9]), ...
static void THVector_(interleaved_normal_fill_16)(scalar_t *data,
const scalar_t mean,
const scalar_t stddev)
{
for (int j = 0; j < 8; ++j) {
const scalar_t u1 = 1 - data[j]; // [0, 1) -> (0, 1] for log.
const scalar_t u2 = data[j + 8];
const scalar_t radius = sqrt(-2 * log(u1));
const scalar_t theta = 2.0f * M_PI * u2;
data[j] = radius * cos(theta) * stddev + mean;
data[j + 8] = radius * std::sin(theta) * stddev + mean;
}
}
void THVector_(normal_fill_DEFAULT)(scalar_t *data,
int64_t size,
at::Generator *generator,
const scalar_t mean,
const scalar_t stddev)
{
THAssert(size >= 16 && "Size must be >= 16 for normal fill");
auto gen = at::get_generator_or_default<at::CPUGenerator>(generator, at::detail::getDefaultCPUGenerator());
// See Note [Acquire lock when using random generators]
std::lock_guard<std::mutex> lock(gen->mutex_);
for (int64_t i = 0; i < size; ++i) {
#ifdef TH_REAL_IS_FLOAT
at::uniform_real_distribution<float> uniform(0, 1);
data[i] = uniform(gen);
#else
at::uniform_real_distribution<double> uniform(0, 1);
data[i] = uniform(gen);
#endif
}
for (int64_t i = 0; i < size - 15; i += 16) {
THVector_(interleaved_normal_fill_16)(data + i, mean, stddev);
}
if (size % 16 != 0) {
// Recompute the last 16 values.
data = data + size - 16;
for (int64_t i = 0; i < 16; ++i) {
#ifdef TH_REAL_IS_FLOAT
at::uniform_real_distribution<float> uniform(0, 1);
data[i] = uniform(gen);
#else
at::uniform_real_distribution<double> uniform(0, 1);
data[i] = uniform(gen);
#endif
}
THVector_(interleaved_normal_fill_16)(data, mean, stddev);
}
}
#define VECTOR_IMPLEMENT_FUNCTION(NAME, CFUNC) \
void THVector_(NAME)(scalar_t *y, const scalar_t *x, const ptrdiff_t n) \
{ \
ptrdiff_t i = 0; \
for(; i<n-4; i+=4) \
{ \
y[i] = CFUNC(x[i]); \
y[i+1] = CFUNC(x[i+1]); \
y[i+2] = CFUNC(x[i+2]); \
y[i+3] = CFUNC(x[i+3]); \
} \
for(; i < n; i++) \
y[i] = CFUNC(x[i]); \
} \
#define VECTOR_IMPLEMENT_FUNCTION_VALUE(NAME, CFUNC) \
void THVector_(NAME)(scalar_t *y, const scalar_t *x, const scalar_t c, const ptrdiff_t n) \
{ \
ptrdiff_t i = 0; \
for(; i<n-4; i+=4) \
{ \
y[i] = CFUNC(x[i], c); \
y[i+1] = CFUNC(x[i+1], c); \
y[i+2] = CFUNC(x[i+2], c); \
y[i+3] = CFUNC(x[i+3], c); \
} \
for(; i < n; i++) \
y[i] = CFUNC(x[i], c); \
} \
/* floating point only now */
#if defined(TH_REAL_IS_FLOAT) || defined(TH_REAL_IS_DOUBLE)
#if defined (TH_REAL_IS_FLOAT)
#define TH_MATH_NAME(fn) fn##f
#else
#define TH_MATH_NAME(fn) fn
#endif
VECTOR_IMPLEMENT_FUNCTION(sigmoid_DEFAULT,TH_MATH_NAME(TH_sigmoid))
VECTOR_IMPLEMENT_FUNCTION(exp,TH_MATH_NAME(exp))
VECTOR_IMPLEMENT_FUNCTION(erf,TH_MATH_NAME(erf))
VECTOR_IMPLEMENT_FUNCTION(erfc,TH_MATH_NAME(erfc))
VECTOR_IMPLEMENT_FUNCTION(cos,TH_MATH_NAME(cos))
VECTOR_IMPLEMENT_FUNCTION(acos,TH_MATH_NAME(acos))
VECTOR_IMPLEMENT_FUNCTION(cosh,TH_MATH_NAME(cosh))
VECTOR_IMPLEMENT_FUNCTION(tan,TH_MATH_NAME(tan))
VECTOR_IMPLEMENT_FUNCTION(atan,TH_MATH_NAME(atan))
VECTOR_IMPLEMENT_FUNCTION(tanh,TH_MATH_NAME(tanh))
VECTOR_IMPLEMENT_FUNCTION_VALUE(pow,TH_MATH_NAME(pow))
VECTOR_IMPLEMENT_FUNCTION(rsqrt,TH_MATH_NAME(TH_rsqrt))
VECTOR_IMPLEMENT_FUNCTION(ceil,TH_MATH_NAME(ceil))
VECTOR_IMPLEMENT_FUNCTION(floor,TH_MATH_NAME(floor))
VECTOR_IMPLEMENT_FUNCTION(round,TH_MATH_NAME(nearbyint))
VECTOR_IMPLEMENT_FUNCTION(trunc,TH_MATH_NAME(trunc))
VECTOR_IMPLEMENT_FUNCTION(cinv, TH_MATH_NAME(1.0) / )
#undef TH_MATH_NAME
#endif /* floating point only part */
VECTOR_IMPLEMENT_FUNCTION(neg,-)
#endif /* non bool only part */
#endif