| 220 | } |
| 221 | |
| 222 | bool Run(Node* node) |
| 223 | { |
| 224 | Tensor* input_tensor = node->GetInputTensor(0); |
| 225 | Tensor* output_tensor = node->GetOutputTensor(0); |
| 226 | const std::vector<int>& dims = input_tensor->GetShape().GetDim(); |
| 227 | Softmax* softmax_op = dynamic_cast<Softmax*>(node->GetOp()); |
| 228 | SoftmaxParam* param_ = softmax_op->GetParam(); |
| 229 | float* input = ( float* )get_tensor_mem(input_tensor); |
| 230 | float* output = ( float* )get_tensor_mem(output_tensor); |
| 231 | |
| 232 | |
| 233 | int dim_size = dims.size(); |
| 234 | int axis = param_->axis; |
| 235 | |
| 236 | if (dim_size == 1) // axis == 0 |
| 237 | { |
| 238 | int w = dims[0]; |
| 239 | float* ptr = input; |
| 240 | float* output_ptr = output; |
| 241 | |
| 242 | // get max |
| 243 | float max = -__FLT_MAX__; |
| 244 | float32x4_t _max4 = vdupq_n_f32(max); |
| 245 | for(int i = 0; i < (w & -4); i += 4) |
| 246 | { |
| 247 | float32x4_t _in = vld1q_f32(ptr + i); |
| 248 | _max4 = vmaxq_f32(_max4, _in); |
| 249 | } |
| 250 | max = vmaxvq_f32(_max4); |
| 251 | float32x2_t _max2 = vdup_n_f32(max); |
| 252 | for (int j = (w & ~3);j<(w & -2);j+=2) |
| 253 | { |
| 254 | float32x2_t _in = vld1_f32(ptr + j); |
| 255 | _max2 = vmax_f32(_max2, _in); |
| 256 | } |
| 257 | max = vpmaxs_f32(_max2); |
| 258 | for (int j=(w & ~1); j<w; j++) |
| 259 | { |
| 260 | max = std::max(max, ptr[j]); |
| 261 | } |
| 262 | |
| 263 | // get sum |
| 264 | float sum = 0.f; |
| 265 | float32x4_t _sum4 = vdupq_n_f32(0.0f); |
| 266 | _max4 = vdupq_n_f32(max); |
| 267 | for(int i = 0; i < (w & -4); i += 4) |
| 268 | { |
| 269 | float32x4_t _in = vld1q_f32(ptr + i); |
| 270 | float32x4_t _out = vexpq10_f32(vsubq_f32(_in, _max4)); |
| 271 | vst1q_f32(output_ptr+i, _out); |
| 272 | _sum4 = vaddq_f32(_sum4, _out); |
| 273 | } |
| 274 | float32x2_t _sum2 = vdup_n_f32(0.0f); |
| 275 | _max2 = vdup_n_f32(max); |
| 276 | for(int i = (w & ~3); i < (w & -2); i += 2) |
| 277 | { |
| 278 | float32x2_t _in = vld1_f32(ptr + i); |
| 279 | float32x2_t _out = vexp10_f32(vsub_f32(_in, _max2)); |
nothing calls this directly
no test coverage detected