Record all the model prediction results in UKM

For multi-output models, we need to record all outputs, not only the
first one.

BUG=1394943

Change-Id: I511f2032472f3b9c47e789418f67a596f2cc241d
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4261997
Commit-Queue: Min Qin <[email protected]>
Reviewed-by: Siddhartha S <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1109302}
diff --git a/components/segmentation_platform/internal/segmentation_ukm_helper.cc b/components/segmentation_platform/internal/segmentation_ukm_helper.cc
index 5421e73..b731ab8 100644
--- a/components/segmentation_platform/internal/segmentation_ukm_helper.cc
+++ b/components/segmentation_platform/internal/segmentation_ukm_helper.cc
@@ -21,6 +21,7 @@
 #define CALL_MEMBER_FN(obj, func) ((obj).*(func))
 #define ARRAY_SIZE(x) (sizeof(x) / sizeof(x)[0])
 
+using segmentation_platform::SegmentationUkmHelper;
 using segmentation_platform::proto::SegmentId;
 using ukm::builders::Segmentation_ModelExecution;
 
@@ -80,6 +81,18 @@
     &Segmentation_ModelExecution::SetInput48,
     &Segmentation_ModelExecution::SetInput49};
 
+const UkmMemberFn kSegmentationUkmPredictionResultMethods[] = {
+    &Segmentation_ModelExecution::SetPredictionResult1,
+    &Segmentation_ModelExecution::SetPredictionResult2,
+    &Segmentation_ModelExecution::SetPredictionResult3,
+    &Segmentation_ModelExecution::SetPredictionResult4,
+    &Segmentation_ModelExecution::SetPredictionResult5,
+    &Segmentation_ModelExecution::SetPredictionResult6,
+    &Segmentation_ModelExecution::SetPredictionResult7,
+    &Segmentation_ModelExecution::SetPredictionResult8,
+    &Segmentation_ModelExecution::SetPredictionResult9,
+    &Segmentation_ModelExecution::SetPredictionResult10};
+
 const UkmMemberFn kSegmentationUkmOutputMethods[] = {
     &Segmentation_ModelExecution::SetActualResult,
     &Segmentation_ModelExecution::SetActualResult2,
@@ -87,9 +100,19 @@
     &Segmentation_ModelExecution::SetActualResult4,
     &Segmentation_ModelExecution::SetActualResult5,
     &Segmentation_ModelExecution::SetActualResult6};
-
 }  // namespace
 
+// Helper method to add model prediction results to UKM log.
+void AddPredictionResultToUkmModelExecution(
+    ukm::builders::Segmentation_ModelExecution* model_execution,
+    const std::vector<float>& results) {
+  CHECK_LE(results.size(), ARRAY_SIZE(kSegmentationUkmPredictionResultMethods));
+  for (size_t i = 0; i < results.size(); ++i) {
+    CALL_MEMBER_FN(*model_execution, kSegmentationUkmPredictionResultMethods[i])
+    (SegmentationUkmHelper::FloatToInt64(results[i]));
+  }
+}
+
 namespace segmentation_platform {
 
 SegmentationUkmHelper::SegmentationUkmHelper() {
@@ -126,7 +149,7 @@
     SegmentId segment_id,
     int64_t model_version,
     const ModelProvider::Request& input_tensor,
-    float result) {
+    const std::vector<float>& results) {
   ukm::SourceId source_id = ukm::NoURLSourceId();
   ukm::builders::Segmentation_ModelExecution execution_result(source_id);
 
@@ -136,9 +159,8 @@
     return ukm::kInvalidSourceId;
   }
 
-  // TODO(xingliu): Also record continuous outputs for model execution.
-  execution_result.SetPredictionResult(FloatToInt64(result))
-      .Record(ukm::UkmRecorder::Get());
+  AddPredictionResultToUkmModelExecution(&execution_result, results);
+  execution_result.Record(ukm::UkmRecorder::Get());
   return source_id;
 }
 
@@ -162,9 +184,9 @@
   }
 
   if (prediction_result.has_value() && prediction_result->result_size() > 0) {
-    // TODO(ritikagup): Add support for uploading multiple outputs.
-    execution_result.SetPredictionResult(
-        FloatToInt64(prediction_result->result()[0]));
+    std::vector<float> results(prediction_result->result().begin(),
+                               prediction_result->result().end());
+    AddPredictionResultToUkmModelExecution(&execution_result, results);
   }
   if (selected_segment.has_value()) {
     execution_result.SetSelectionResult(selected_segment->segment_id);