#include "caffe2/operators/softmax_utils.h" #include "caffe2/core/context.h" #include "caffe2/utils/eigen_utils.h" #include "caffe2/utils/math.h" namespace caffe2 { namespace softmax_utils { #define CAFFE2_SPECIALIZED_SOFTMAX_CPU(T) \ template <> \ void SoftmaxCPU( \ const int N, \ const int D, \ const bool logarithmic, \ const T* X, \ T* Y, \ T* scratch, \ CPUContext* context) { \ ConstEigenArrayMap X_arr(X, D, N); \ EigenArrayMap Y_arr(Y, D, N); \ EigenVectorArrayMap scratch_arr(scratch, N); \ scratch_arr = X_arr.colwise().maxCoeff().transpose(); \ Y_arr = X_arr.rowwise() - scratch_arr.transpose(); \ math::Exp(N * D, Y, Y, context); \ if (logarithmic) { \ scratch_arr += Y_arr.colwise().sum().log().transpose(); \ Y_arr = X_arr.rowwise() - scratch_arr.transpose(); \ } else { \ scratch_arr = Y_arr.colwise().sum().inverse().transpose(); \ Y_arr = Y_arr.rowwise() * scratch_arr.transpose(); \ } \ } CAFFE2_SPECIALIZED_SOFTMAX_CPU(float) #undef CAFFE2_SPECIALIZED_SOFTMAX_CPU } // namespace softmax_utils } // namespace caffe2