def build_groups()

in perfrunbook/utilities/measure_aggregated_pmu_stats.py [0:0]


def build_groups(platforms):
    """
    Takes a list of counter ratios and divides them into a minimal set of groups that we
    can multiplex onto the CPU PMU.  Numerators and denominators are scheduled together
    to avoid artifacts with the ratios.
    """
    # Counter groupings by denominator
    pmu_sets = {}
    for platform in platforms:
        groups = defaultdict(list)
        MAX_COUNTERS_IN_GROUP = platform.get_max_ctrs()

        counters = platform.get_counters()
        pmu = None
        for ctr in counters:
            denom = ctr.get_denominator()
            numer = ctr.get_numerator()
            pmu = ctr.get_pmu()

            groups[denom].append(numer)

        counter_sets = []
        current_set = set()

        for denom in groups.keys():
            # Make a copy of the list because we're going to mutate it
            numerators = groups[denom].copy()
            while len(numerators):
                # Make sure to add the denominator to the set, if and only if
                # it is not there and we have space for another numerator.
                # One exception is for counter ratios with no denominator.
                if (denom) and (denom not in current_set):
                    if len(current_set) < (MAX_COUNTERS_IN_GROUP - 1):
                        current_set.add(denom)
                    else:
                        # Counter set cannot fit a new denominator and
                        # at least 1 numerator in group
                        counter_sets.append(current_set)
                        current_set = set()
                        continue

                if len(current_set) < MAX_COUNTERS_IN_GROUP:
                    current_set.add(numerators.pop(0))
                else:
                    # Out of space for a numerator
                    counter_sets.append(current_set)
                    current_set = set()

        # Add final counter set.
        if len(current_set):
            counter_sets.append(current_set)
        if pmu not in pmu_sets:
            pmu_sets[pmu] = counter_sets
        else:
            pmu_sets[pmu].extend(counter_sets)

    return pmu_sets