// See docs in ../ops/nn_ops.cc. #define EIGEN_USE_THREADS #include "tensorflow/core/framework/numeric_op.h" #include "tensorflow/core/framework/op_kernel.h" #include "tensorflow/core/framework/register_types.h" #include "tensorflow/core/kernels/softplus_op.h" #include "tensorflow/core/public/tensor.h" #include "tensorflow/core/lib/core/errors.h" #include "third_party/eigen3/unsupported/Eigen/CXX11/Tensor" namespace tensorflow { typedef Eigen::ThreadPoolDevice CPUDevice; typedef Eigen::GpuDevice GPUDevice; template class SoftplusOp : public UnaryElementWiseOp> { public: using UnaryElementWiseOp>::UnaryElementWiseOp; void Operate(OpKernelContext* context, const Tensor& input, Tensor* output) { functor::Softplus functor; functor(context->eigen_device(), input.flat(), output->flat()); } }; template class SoftplusGradOp : public BinaryElementWiseOp> { public: using BinaryElementWiseOp>::BinaryElementWiseOp; // INPUTS: // g (gradients): backpropagated gradients // a (inputs): inputs that were passed to SoftplusOp() // OUTPUT: // gradients to backprop template void Operate(OpKernelContext* context, const Tensor& g, const Tensor& a, Tensor* output) { OP_REQUIRES(context, a.IsSameSize(g), errors::InvalidArgument("g and a must be the same size")); functor::SoftplusGrad functor; functor(context->eigen_device(), g.flat(), a.flat(), output->flat()); } }; #define REGISTER_KERNELS(type) \ REGISTER_KERNEL_BUILDER( \ Name("Softplus").Device(DEVICE_CPU).TypeConstraint("T"), \ SoftplusOp); \ REGISTER_KERNEL_BUILDER( \ Name("SoftplusGrad").Device(DEVICE_CPU).TypeConstraint("T"), \ SoftplusGradOp); TF_CALL_REAL_NUMBER_TYPES(REGISTER_KERNELS); #undef REGISTER_KERNELS #if GOOGLE_CUDA // Forward declarations of the functor specializations for GPU. namespace functor { #define DECLARE_GPU_SPEC(T) \ template <> \ void Softplus::operator()( \ const GPUDevice& d, typename TTypes::ConstTensor features, \ typename TTypes::Tensor activations); \ extern template struct Softplus; \ \ template <> \ void SoftplusGrad::operator()( \ const GPUDevice& d, typename TTypes::ConstTensor gradients, \ typename TTypes::ConstTensor features, \ typename TTypes::Tensor backprops); \ extern template struct SoftplusGrad; TF_CALL_GPU_NUMBER_TYPES(DECLARE_GPU_SPEC); } // namespace functor // Registration of the GPU implementations. #define REGISTER_GPU_KERNELS(type) \ REGISTER_KERNEL_BUILDER( \ Name("Softplus").Device(DEVICE_GPU).TypeConstraint("T"), \ SoftplusOp); \ REGISTER_KERNEL_BUILDER( \ Name("SoftplusGrad").Device(DEVICE_GPU).TypeConstraint("T"), \ SoftplusGradOp); TF_CALL_GPU_NUMBER_TYPES(REGISTER_GPU_KERNELS); #undef REGISTER_GPU_KERNELS #endif // GOOGLE_CUDA } // namespace tensorflow