blob: bb9753a67857ce8c0a8f280a70e6eca6aca3dc16 [file] [log] [blame]
#include "THCUNN.h"
#include "THCHalf.h"
#include "THCHalfAutoNumerics.cuh"
#include <THC/THCApply.cuh>
template <typename T>
struct logSigmoid_updateOutput_functor
{
__device__ void operator()(T *output, const T *input) const {
*output = -THCNumerics<T>::log(1.f + THCNumerics<T>::exp(- *input));
}
};
template <typename T>
struct logSigmoid_updateGradInput_functor
{
__device__ void operator()(T *gradInput, const T *input, const T *gradOutput) const {
const T z = THCNumerics<T>::exp(- *input);
*gradInput = *gradOutput * z / (1.f + z);
}
};
#ifdef CUDA_HALF_TENSOR
template <>
struct logSigmoid_updateOutput_functor<half> {
__device__ __forceinline__ void operator()(half* output, const half *input) const {
#ifdef CUDA_HALF_INSTRUCTIONS
const half one = __float2half(1.f);
*output = __hneg(THCNumerics<half>::log(one + THCNumerics<half>::exp(__hneg(*input))));
#else
float in = __half2float(*input);
*output = __float2half(-THCNumerics<float>::log(1.f + THCNumerics<float>::exp(-in)));
#endif
}
};
template <>
struct logSigmoid_updateGradInput_functor<half> {
__device__ __forceinline__ void operator()(half* gradInput, const half *input, const half *gradOutput) const {
#ifdef CUDA_HALF_INSTRUCTIONS
const half one = __float2half(1.f);
const half in_exp = THCNumerics<half>::exp(__hneg(*input));
*gradInput = hdiv(__hmul(*gradOutput, in_exp), __hadd(one, in_exp));
#else
const float in_exp = THCNumerics<float>::exp(-(__half2float(*input)));
const float go = __half2float(*gradOutput);
*gradInput = __float2half(go * in_exp / (1.f + in_exp));
#endif
}
};
#endif
#include "generic/LogSigmoid.cu"
#include "THCGenerateFloatTypes.h"