MCPcopy Create free account
hub / github.com/DeepRec-AI/DeepRec / MeanImpl

Function MeanImpl

tensorflow/lite/kernels/internal/optimized/optimized_ops.h:849–951  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

847#endif // USE_NEON
848
849inline void MeanImpl(const tflite::MeanParams& op_params,
850 const RuntimeShape& input_shape, const uint8_t* input_data,
851 int32 input_zero_point, float input_scale,
852 const RuntimeShape& output_shape, uint8_t* output_data,
853 int32 output_zero_point, float output_scale,
854 int start_depth, int end_depth) {
855 gemmlowp::ScopedProfilingLabel label("Mean4D/Uint8/MeanImpl");
856
857 // Current implementation only supports dimension equals 4 and simultaneous
858 // reduction over width and height.
859 const int output_batch = output_shape.Dims(0);
860 const int output_height = output_shape.Dims(2);
861 const int output_width = output_shape.Dims(2);
862 const int input_height = input_shape.Dims(1);
863 const int input_width = input_shape.Dims(2);
864 const float num_elements_in_axis = input_width * input_height;
865
866 TFLITE_DCHECK_EQ(op_params.axis_count, 2);
867 TFLITE_DCHECK((op_params.axis[0] == 1 && op_params.axis[1] == 2) ||
868 (op_params.axis[0] == 2 && op_params.axis[1] == 1));
869 TFLITE_DCHECK_EQ(output_height, 1);
870 TFLITE_DCHECK_EQ(output_width, 1);
871
872 const bool ordinary_mean =
873 (input_zero_point == output_zero_point && input_scale == output_scale);
874 float scale = 0.0f, bias = 0.0f;
875 if (!ordinary_mean) {
876 scale = input_scale / output_scale;
877 bias = -input_zero_point * scale + 0.5;
878 }
879
880#ifdef USE_NEON
881 const float32x4_t num_elements_dup = vdupq_n_f32(num_elements_in_axis);
882 // This is only an approximation as NEON does not offer division instruction.
883 const float32x4_t scale_dup = vdupq_n_f32(scale);
884 const float32x4_t num_elements_reverse = vrecpeq_f32(num_elements_dup);
885 float32x4_t zero_point_with_bias_dup = vdupq_n_f32(output_zero_point + bias);
886#endif // USE_NEON
887
888 for (int out_b = 0; out_b < output_batch; ++out_b) {
889 int out_d = start_depth;
890#ifdef USE_NEON
891
892 for (; out_d < end_depth - 8; out_d += 8) {
893 float32x4_t temp_sum_1 = vdupq_n_f32(0);
894 float32x4_t temp_sum_2 = vdupq_n_f32(0);
895 for (int in_h = 0; in_h < input_height; ++in_h) {
896 for (int in_w = 0; in_w < input_width; ++in_w) {
897 const uint8_t* input_data_ptr =
898 input_data + Offset(input_shape, out_b, in_h, in_w, out_d);
899 uint8x8_t input_data_val = vld1_u8(input_data_ptr);
900 int16x8_t input_data_val_shift =
901 vreinterpretq_s16_u16(vmovl_u8(input_data_val));
902 float32x4_t input_float_1 =
903 vcvtq_f32_s32(vmovl_s16(vget_high_s16(input_data_val_shift)));
904 float32x4_t input_float_2 =
905 vcvtq_f32_s32(vmovl_s16(vget_low_s16(input_data_val_shift)));
906 temp_sum_1 = vaddq_f32(temp_sum_1, input_float_1);

Callers 2

RunMethod · 0.70
MeanFunction · 0.70

Calls 5

DivideSumForMeanImplFunction · 0.85
RoundToNearestUnsignedFunction · 0.85
DimsMethod · 0.80
OffsetFunction · 0.50
roundFunction · 0.50

Tested by

no test coverage detected