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

Function Mean

tensorflow/lite/kernels/internal/optimized/integer_ops/mean.h:175–231  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

173};
174
175inline void Mean(const tflite::MeanParams& op_params,
176 const RuntimeShape& unextended_input_shape,
177 const int8_t* input_data, int32 input_zero_point,
178 float input_scale, const RuntimeShape& unextended_output_shape,
179 int8_t* output_data, int32 output_zero_point,
180 float output_scale, CpuBackendContext* cpu_backend_context) {
181 gemmlowp::ScopedProfilingLabel label("Mean4D/Int8");
182 // Current implementation only supports dimension equals 4 and simultaneous
183 // reduction over width and height.
184 TFLITE_CHECK_EQ(unextended_input_shape.DimensionsCount(), 4);
185 TFLITE_CHECK_LE(unextended_output_shape.DimensionsCount(), 4);
186 const RuntimeShape input_shape =
187 RuntimeShape::ExtendedShape(4, unextended_input_shape);
188 const RuntimeShape output_shape =
189 RuntimeShape::ExtendedShape(4, unextended_output_shape);
190 const int output_height = output_shape.Dims(1);
191 const int output_width = output_shape.Dims(2);
192 const int output_depth = output_shape.Dims(3);
193
194 TFLITE_DCHECK_EQ(op_params.axis_count, 2);
195 TFLITE_DCHECK((op_params.axis[0] == 1 && op_params.axis[1] == 2) ||
196 (op_params.axis[0] == 2 && op_params.axis[1] == 1));
197 TFLITE_DCHECK_EQ(output_height, 1);
198 TFLITE_DCHECK_EQ(output_width, 1);
199
200 constexpr int kMinDepthPerThread = 8;
201 int thread_count = output_depth / kMinDepthPerThread;
202 thread_count = thread_count > 0 ? thread_count : 1;
203 const int capped_thread_count =
204 std::min(thread_count, cpu_backend_context->max_num_threads());
205
206 if (capped_thread_count == 1) {
207 MeanImpl(op_params, input_shape, input_data, input_zero_point, input_scale,
208 output_shape, output_data, output_zero_point, output_scale, 0,
209 output_depth);
210 } else {
211 // Instead parrallel for batch, we loop for the output_depth since batch
212 // is typical 1.
213 std::vector<MeanWorkerTask> tasks;
214 // TODO(b/131746020) don't create new heap allocations every time.
215 // At least we make it a single heap allocation by using reserve().
216 tasks.reserve(capped_thread_count);
217 int depth_start = 0;
218 for (int i = 0; i < capped_thread_count; ++i) {
219 // Try to distribute the tasks as even as possible.
220 int depth_end = depth_start +
221 (output_depth - depth_start) / (capped_thread_count - i);
222 tasks.emplace_back(op_params, input_shape, input_data, input_zero_point,
223 input_scale, output_shape, output_data,
224 output_zero_point, output_scale, depth_start,
225 depth_end);
226 depth_start = depth_end;
227 }
228 cpu_backend_threadpool::Execute(tasks.size(), tasks.data(),
229 cpu_backend_context);
230 }
231}
232

Callers

nothing calls this directly

Calls 10

DimensionsCountMethod · 0.80
DimsMethod · 0.80
max_num_threadsMethod · 0.80
MeanImplFunction · 0.70
minFunction · 0.50
ExecuteFunction · 0.50
reserveMethod · 0.45
emplace_backMethod · 0.45
sizeMethod · 0.45
dataMethod · 0.45

Tested by

no test coverage detected