| 211 | explicit MklSoftmaxOp(OpKernelConstruction* context) : OpKernel(context) {} |
| 212 | |
| 213 | void Compute(OpKernelContext* context) override { |
| 214 | try { |
| 215 | auto cpu_engine = engine(ENGINE_CPU, 0); |
| 216 | // src_tensor points to the 0-th input of global data struct "context". |
| 217 | size_t src_idx = 0; |
| 218 | const Tensor& src_tensor = MklGetInput(context, src_idx); |
| 219 | MklDnnShape src_mkl_shape; |
| 220 | GetMklShape(context, src_idx, &src_mkl_shape); |
| 221 | |
| 222 | // src_dims is the dimension of src_tensor. |
| 223 | // Dim of the dst will also be same as src_dims. |
| 224 | auto src_tf_shape = src_mkl_shape.IsMklTensor() |
| 225 | ? src_mkl_shape.GetTfShape() |
| 226 | : src_tensor.shape(); |
| 227 | const int input_dims = src_tf_shape.dims(); |
| 228 | memory::dims src_dims; |
| 229 | int axis; |
| 230 | if (src_mkl_shape.IsMklTensor()) { |
| 231 | src_dims = src_mkl_shape.GetSizesAsMklDnnDims(); |
| 232 | axis = 1; |
| 233 | } else { |
| 234 | src_dims = TFShapeToMklDnnDims(src_tf_shape); |
| 235 | axis = input_dims - 1; |
| 236 | } |
| 237 | MKL_TENSOR_FORMAT layout_type; |
| 238 | // In OneDNN, data format passed to OneDNN softmax op depends on dimension of |
| 239 | // the input tensor. Here "x" data format in OneDNN is used for 1 dim tensor, |
| 240 | // "nc" for 2 dim tensor, "tnc" for 3 dim tensor, "nchw" for 4 dim tensor, |
| 241 | // and "ncdhw" for 5 dim tensor. Each of the symbols has the following |
| 242 | // meaning: n = batch, c = channels, t = sequence length, h = height, w = |
| 243 | // width, d = depth. When src tensor is OneDNN, layout_type here is only used |
| 244 | // for setting TF layout type of output tensor. When input is TF Tensor, |
| 245 | // layout here is no special sense. We use axis to define on which |
| 246 | // dimension to do softmax. |
| 247 | switch (input_dims) { |
| 248 | case 1: |
| 249 | layout_type = MKL_TENSOR_FORMAT_X; |
| 250 | break; |
| 251 | case 2: |
| 252 | layout_type = MKL_TENSOR_FORMAT_NC; |
| 253 | break; |
| 254 | case 3: |
| 255 | layout_type = MKL_TENSOR_FORMAT_TNC; |
| 256 | break; |
| 257 | case 4: |
| 258 | if (src_mkl_shape.IsMklTensor()) { |
| 259 | layout_type = MKL_TENSOR_FORMAT_NHWC; |
| 260 | } else { |
| 261 | layout_type = MKL_TENSOR_FORMAT_NCHW; |
| 262 | } |
| 263 | break; |
| 264 | case 5: |
| 265 | if (src_mkl_shape.IsMklTensor()) { |
| 266 | layout_type = MKL_TENSOR_FORMAT_NDHWC; |
| 267 | } else { |
| 268 | layout_type = MKL_TENSOR_FORMAT_NCDHW; |
| 269 | } |
| 270 | break; |
nothing calls this directly
no test coverage detected