@@ -23,6 +23,7 @@ limitations under the License.
2323#include " google/protobuf/util/message_differencer.h"
2424#include " xla/tsl/platform/types.h"
2525#include " plugin/xprof/protobuf/hardware_types.pb.h"
26+ #include " plugin/xprof/protobuf/op_metrics.pb.h"
2627#include " plugin/xprof/protobuf/op_stats.pb.h"
2728#include " plugin/xprof/protobuf/power_metrics.pb.h"
2829#include " plugin/xprof/protobuf/steps_db.pb.h"
@@ -234,6 +235,74 @@ TEST(CombineAllOpStatsTest, CombineDisaggregatedServingStats) {
234235 1e-6 );
235236}
236237
238+ TEST (CombineAllOpStatsTest, CombineDeviceOpMetricsDbWithChildren) {
239+ OpStats dst_op_stats, op_stats_1, op_stats_2;
240+
241+ // Set up op_stats_1 with one device op that has children.
242+ {
243+ auto * db = op_stats_1.mutable_device_op_metrics_db ();
244+ auto * op = db->add_metrics_db ();
245+ op->set_name (" parent_op" );
246+ op->set_hlo_module_id (123 );
247+ op->set_occurrences (1 );
248+ op->set_time_ps (100 );
249+
250+ auto * child_db = op->mutable_children ();
251+ auto * child_op = child_db->add_metrics_db ();
252+ child_op->set_name (" Add_1" );
253+ child_op->set_hlo_module_id (123 );
254+ child_op->set_occurrences (5 );
255+ child_op->set_time_ps (400 );
256+ }
257+
258+ // Set up op_stats_2 with the same device op that has other children.
259+ {
260+ auto * db = op_stats_2.mutable_device_op_metrics_db ();
261+ auto * op = db->add_metrics_db ();
262+ op->set_name (" parent_op" );
263+ op->set_hlo_module_id (123 );
264+ op->set_occurrences (2 );
265+ op->set_time_ps (200 );
266+
267+ auto * child_db = op->mutable_children ();
268+ auto * child_op = child_db->add_metrics_db ();
269+ child_op->set_name (" Add_1" );
270+ child_op->set_hlo_module_id (123 );
271+ child_op->set_occurrences (10 );
272+ child_op->set_time_ps (800 );
273+ }
274+
275+ OpStatsInfo op_stats_info_1 (&op_stats_1, TPU , 0 );
276+ OpStatsInfo op_stats_info_2 (&op_stats_2, TPU , 1 );
277+
278+ std::vector<OpStatsInfo> all_op_stats_info = {op_stats_info_1,
279+ op_stats_info_2};
280+
281+ StepDatabaseResult dummy_step_db_result;
282+ absl::flat_hash_map<uint32_t /* host_id*/ , const StepDatabaseResult*> result;
283+ result.insert ({0 , &dummy_step_db_result});
284+ StepIntersection dummy_step_intersection = StepIntersection (1 , result);
285+
286+ CombineAllOpStats (all_op_stats_info, dummy_step_intersection, &dst_op_stats);
287+
288+ // Verify that the combined op metrics has the parent_op.
289+ const auto & combined_db = dst_op_stats.device_op_metrics_db ();
290+ ASSERT_EQ (combined_db.metrics_db_size (), 1 );
291+ const auto & combined_op = combined_db.metrics_db (0 );
292+ EXPECT_EQ (combined_op.name (), " parent_op" );
293+ EXPECT_EQ (combined_op.occurrences (), 3 );
294+ EXPECT_EQ (combined_op.time_ps (), 300 );
295+
296+ // Verify that the children are merged without duplication.
297+ const auto & combined_children_db = combined_op.children ();
298+ ASSERT_EQ (combined_children_db.metrics_db_size (), 1 );
299+
300+ const auto & child_op = combined_children_db.metrics_db (0 );
301+ EXPECT_EQ (child_op.name (), " Add_1" );
302+ EXPECT_EQ (child_op.occurrences (), 15 );
303+ EXPECT_EQ (child_op.time_ps (), 1200 );
304+ }
305+
237306} // namespace
238307} // namespace profiler
239308} // namespace tensorflow
0 commit comments