1
    2
    3
    4
    5
    6
    7
    8
    9
   10
   11
   12
   13
   14
   15
   16
   17
   18
   19
   20
   21
   22
   23
   24
   25
   26
   27
   28
   29
   30
   31
   32
   33
   34
   35
   36
   37
   38
   39
   40
   41
   42
   43
   44
   45
   46
   47
   48
   49
   50
   51
   52
   53
   54
   55
   56
   57
   58
   59
   60
   61
   62
   63
   64
   65
   66
   67
   68
   69
   70
   71
   72
   73
   74
   75
   76
   77
   78
   79
   80
   81
   82
   83
   84
   85
   86
   87
   88
   89
   90
   91
   92
   93
   94
   95
   96
   97
   98
   99
  100
  101
  102
  103
  104
  105
  106
  107
  108
  109
  110
  111
  112
  113
  114
  115
  116
  117
  118
  119
  120
  121
  122
  123
  124
  125
  126
  127
  128
  129
  130
  131
  132
  133

content / test / gpu / unexpected_passes / gpu_expectations.py [blame]

# Copyright 2021 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""GPU-specific implementation of the unexpected passes' expectations module."""

import collections
import logging
import os
from typing import FrozenSet, List, Optional, Set

import dataclasses  # Built-in, but pylint gives an ordering false positive.

import validate_tag_consistency

from gpu_tests import gpu_integration_test

from unexpected_passes_common import data_types
from unexpected_passes_common import expectations

EXPECTATIONS_DIR = os.path.realpath(
    os.path.join(os.path.dirname(__file__), '..', 'gpu_tests',
                 'test_expectations'))


@dataclasses.dataclass
class _OverlappingTagConfig:
  identifier_tags: List[Set[str]]
  tags_to_remove: Set[str]

  def AppliesToTags(self, typ_tags: Set[str]) -> bool:
    for it in self.identifier_tags:
      if it <= typ_tags:
        return True
    return False


_SPECIFIC_MAC_VERSIONS = validate_tag_consistency.TAG_SPECIALIZATIONS[
    'OS_TAGS']['mac']


def _GenerateMacIdentifierTags(gpu: str) -> List[Set[str]]:
  identifier_tags = []
  for mac_version in _SPECIFIC_MAC_VERSIONS:
    identifier_tags.append({gpu, mac_version})
  return identifier_tags


_DUAL_GPU_MAC_TAG_CONFIGS = [
    # 2015 Macbook Pros.
    _OverlappingTagConfig(identifier_tags=[
        {'amd-0x6821', 'mac'},
        {'amd-0x6821', 'intel-0xd26'},
    ] + _GenerateMacIdentifierTags('amd-0x6821'),
                          tags_to_remove={
                              'intel',
                              'intel-0xd26',
                          }),
    # 15" 2019 Macbook Pros.
    _OverlappingTagConfig(identifier_tags=[
        {'amd-0x67ef', 'mac'},
        {'amd-0x67ef', 'intel-0x3e9b'},
    ] + _GenerateMacIdentifierTags('amd-0x67ef'),
                          tags_to_remove={
                              'intel',
                              'intel-0x3e9b',
                              'intel-gen-9',
                          }),
    # 16" 2019 Macbook Pros.
    _OverlappingTagConfig(identifier_tags=[
        {'amd-0x7340', 'mac'},
        {'amd-0x7340', 'intel-0x3e9b'},
    ] + _GenerateMacIdentifierTags('amd-0x7340'),
                          tags_to_remove={
                              'intel',
                              'intel-0x3e9b',
                              'intel-gen-9',
                          }),
]


class GpuExpectations(expectations.Expectations):
  def __init__(self):
    super().__init__()
    self._known_tags: Optional[Set[str]] = None
    self._expectation_files: Optional[List[str]] = None

  def CreateTestExpectationMap(self, *args,
                               **kwargs) -> data_types.TestExpectationMap:
    expectation_map = super().CreateTestExpectationMap(*args, **kwargs)
    # We currently don't support handling Slow expectations, so drop them
    # immediately so they can't be accidentally removed.
    expectations_to_drop = collections.defaultdict(list)
    for expectation_file, expectation_dict in expectation_map.items():
      for expectation in expectation_dict:
        if 'Slow' in expectation.expected_results:
          expectations_to_drop[expectation_file].append(expectation)
    for expectation_file, expectation_list in expectations_to_drop.items():
      for expectation in expectation_list:
        logging.info(
            'Dropping expectation "%s" from %s since it includes a "Slow" '
            'expected result', expectation.AsExpectationFileString(),
            expectation_file)
        del expectation_map[expectation_file][expectation]
    return expectation_map

  def GetExpectationFilepaths(self) -> List[str]:
    if self._expectation_files is None:
      self._expectation_files = []
      name_mapping = gpu_integration_test.GenerateTestNameMapping()
      for suite_class in name_mapping.values():
        self._expectation_files.extend(suite_class.ExpectationsFiles())
    return self._expectation_files

  def _GetExpectationFileTagHeader(self, _: str) -> str:
    return validate_tag_consistency.TAG_HEADER

  def _GetKnownTags(self) -> Set[str]:
    if self._known_tags is None:
      list_parser = self.ParseTaggedTestListContent(
          self._GetExpectationFileTagHeader(''))
      self._known_tags = set()
      for ts in list_parser.tag_sets:
        self._known_tags |= ts
    return self._known_tags

  def _ConsolidateKnownOverlappingTags(self, typ_tags: FrozenSet[str]
                                       ) -> FrozenSet[str]:
    typ_tags = set(typ_tags)
    for tag_config in _DUAL_GPU_MAC_TAG_CONFIGS:
      if tag_config.AppliesToTags(typ_tags):
        typ_tags -= tag_config.tags_to_remove
        break
    return frozenset(typ_tags)