exc.py 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. from __future__ import annotations
  2. import os
  3. import tempfile
  4. import textwrap
  5. from functools import lru_cache
  6. from typing import Any, Optional, TYPE_CHECKING
  7. from torch._dynamo.exc import BackendCompilerFailed, ShortenTraceback
  8. if TYPE_CHECKING:
  9. import types
  10. from torch.cuda import _CudaDeviceProperties
  11. if os.environ.get("TORCHINDUCTOR_WRITE_MISSING_OPS") == "1":
  12. @lru_cache(None)
  13. def _record_missing_op(target: Any) -> None:
  14. with open(f"{tempfile.gettempdir()}/missing_ops.txt", "a") as fd:
  15. fd.write(str(target) + "\n")
  16. else:
  17. def _record_missing_op(target: Any) -> None: # type: ignore[misc]
  18. pass
  19. class OperatorIssue(RuntimeError):
  20. @staticmethod
  21. def operator_str(target: Any, args: list[Any], kwargs: dict[str, Any]) -> str:
  22. lines = [f"target: {target}"] + [
  23. f"args[{i}]: {arg}" for i, arg in enumerate(args)
  24. ]
  25. if kwargs:
  26. lines.append(f"kwargs: {kwargs}")
  27. return textwrap.indent("\n".join(lines), " ")
  28. class MissingOperatorWithoutDecomp(OperatorIssue):
  29. def __init__(self, target: Any, args: list[Any], kwargs: dict[str, Any]) -> None:
  30. _record_missing_op(target)
  31. super().__init__(f"missing lowering\n{self.operator_str(target, args, kwargs)}")
  32. class MissingOperatorWithDecomp(OperatorIssue):
  33. def __init__(self, target: Any, args: list[Any], kwargs: dict[str, Any]) -> None:
  34. _record_missing_op(target)
  35. super().__init__(
  36. f"missing decomposition\n{self.operator_str(target, args, kwargs)}"
  37. + textwrap.dedent(
  38. f"""
  39. There is a decomposition available for {target} in
  40. torch._decomp.get_decompositions(). Please add this operator to the
  41. `decompositions` list in torch._inductor.decomposition
  42. """
  43. )
  44. )
  45. class LoweringException(OperatorIssue):
  46. def __init__(
  47. self, exc: Exception, target: Any, args: list[Any], kwargs: dict[str, Any]
  48. ) -> None:
  49. super().__init__(
  50. f"{type(exc).__name__}: {exc}\n{self.operator_str(target, args, kwargs)}"
  51. )
  52. class SubgraphLoweringException(RuntimeError):
  53. pass
  54. class InvalidCxxCompiler(RuntimeError):
  55. def __init__(self) -> None:
  56. from . import config
  57. super().__init__(
  58. f"No working C++ compiler found in {config.__name__}.cpp.cxx: {config.cpp.cxx}"
  59. )
  60. class CppWrapperCodegenError(RuntimeError):
  61. def __init__(self, msg: str) -> None:
  62. super().__init__(f"C++ wrapper codegen error: {msg}")
  63. class CppCompileError(RuntimeError):
  64. def __init__(self, cmd: list[str], output: str) -> None:
  65. if isinstance(output, bytes):
  66. output = output.decode("utf-8")
  67. self.cmd = cmd
  68. self.output = output
  69. super().__init__(
  70. textwrap.dedent(
  71. """
  72. C++ compile error
  73. Command:
  74. {cmd}
  75. Output:
  76. {output}
  77. """
  78. )
  79. .strip()
  80. .format(cmd=" ".join(cmd), output=output)
  81. )
  82. def __reduce__(self) -> tuple[type, tuple[list[str], str]]:
  83. return (self.__class__, (self.cmd, self.output))
  84. class CUDACompileError(CppCompileError):
  85. pass
  86. class TritonMissing(ShortenTraceback):
  87. def __init__(self, first_useful_frame: Optional[types.FrameType]) -> None:
  88. super().__init__(
  89. "Cannot find a working triton installation. "
  90. "Either the package is not installed or it is too old. "
  91. "More information on installing Triton can be found at: https://github.com/triton-lang/triton",
  92. first_useful_frame=first_useful_frame,
  93. )
  94. class GPUTooOldForTriton(ShortenTraceback):
  95. def __init__(
  96. self,
  97. device_props: _CudaDeviceProperties,
  98. first_useful_frame: Optional[types.FrameType],
  99. ) -> None:
  100. super().__init__(
  101. f"Found {device_props.name} which is too old to be supported by the triton GPU compiler, "
  102. "which is used as the backend. Triton only supports devices of CUDA Capability >= 7.0, "
  103. f"but your device is of CUDA capability {device_props.major}.{device_props.minor}",
  104. first_useful_frame=first_useful_frame,
  105. )
  106. class InductorError(BackendCompilerFailed):
  107. backend_name = "inductor"
  108. def __init__(
  109. self,
  110. inner_exception: Exception,
  111. first_useful_frame: Optional[types.FrameType],
  112. ) -> None:
  113. self.inner_exception = inner_exception
  114. ShortenTraceback.__init__(
  115. self,
  116. f"{type(inner_exception).__name__}: {inner_exception}",
  117. first_useful_frame=first_useful_frame,
  118. )