def __call__(
        self,
        ground_truth: pd.DataFrame,
    ) -> Union[
        List[float], List[Tuple[float]], Tuple[List[float], List[float]]
    ]:
        """Collect the list of generated feedback scores as input to the benchmark aggregation functions
        Note the order of generated scores must be preserved to match the order of the true labels.

        Args:
            ground_truth (pd.DataFrame): ground truth dataset / collection to evaluate the feedback function on

        Returns:
            List[float]: feedback scores after running the benchmark on all entries in ground truth data
        """

        # TODO: instance type check of ground_truth argument + handle groundtruth_impl

        scores = []
        meta_scores = []
        with ThreadPoolExecutor() as executor:
            future_to_index = {}
            index_to_results = {}

            for index, row in ground_truth.iterrows():
                if "expected_chunks" in row:
                    for expected_chunk in row["expected_chunks"]:
                        future = executor.submit(
                            self.run_score_generation_on_single_row,
                            self.feedback_fn,
                            [row["query"], expected_chunk["text"]],
                        )
                        future_to_index[future] = index
                elif "expected_response" in row:
                    future = executor.submit(
                        self.run_score_generation_on_single_row,
                        self.feedback_fn,
                        [row["query"], row["expected_response"]],
                    )
                    future_to_index[future] = index

            for future in as_completed(future_to_index):
                index = future_to_index[future]
                try:
                    ret = future.result()
                    index_to_results.setdefault(index, []).append(ret)

                except Exception as e:
                    log.error(f"Row generated an exception: {e}")

            # Process results in the original order
            for index in range(len(ground_truth)):
                if index in index_to_results:
                    for ret in index_to_results[index]:
                        if isinstance(ret, float):
                            score = ret
                        else:
                            score, metadata = ret
                            meta_scores.append(metadata)

                        scores.append(score)

        if meta_scores:
            return scores, meta_scores
        else:
            return scores
Collect the list of generated feedback scores as input to the benchmark aggregation functions
        Note the order of generated scores must be preserved to match the order of the true labels.

        Args:
            ground_truth (pd.DataFrame): ground truth dataset / collection to evaluate the feedback function on

        Returns:
            List[float]: feedback scores after running the benchmark on all entries in ground truth data
        
src/benchmark/trulens/benchmark/benchmark_frameworks/tru_benchmark_experiment.py