class_docstr: Class for custom operators in PyTorch.
  
  Use the CustomOp API to create user-defined custom operators that behave
  just like regular PyTorch operators (e.g. torch.sin, torch.mm) when it
  comes to various PyTorch subsystems (like torch.compile).
  
  To construct a `CustomOp`, use `custom_op`.
docstr: Register an implementation for a device type for this CustomOp object.
  
  WARNING: if you're a user, please do not use this directly
  (instead use the torch._custom_ops APIs).
  Also please see the following for a detailed guide on custom ops.
  https://docs.google.com/document/d/1aGWtgxV3HppuxQAdddyPrs74_aEntpkYt9MalnCKnhk
  
  If the CustomOp is passed multiple Tensor inputs with different device
  types, it will dispatch to the registered implementation for the highest
  priority device type among those present.
  The supported device types, in order of priority, are {'cuda', 'cpu'}.
  
  This API is used as a decorator (see examples).
  
  Arguments:
      device_types (str or Iterable[str]): the device type(s) to register the function for.
  
  Examples::
      >>> # xdoctest: +REQUIRES(env:TORCH_DOCTEST_CUDA)
      >>> import numpy as np
      >>> from torch import Tensor
      >>>
      >>> @custom_op("my_library::numpy_cos")
      >>> def numpy_cos(x: Tensor) -> Tensor:
      >>>     ...
      >>>
      >>> # Register an implementation for CPU Tensors
      >>> @numpy_cos.impl('cpu')
      >>> def numpy_cos_impl_cpu(x):
      >>>     return torch.from_numpy(np.cos(x.numpy()))
      >>>
      >>> # Register an implementation for CUDA Tensors
      >>> @numpy_cos.impl('cuda')
      >>> def numpy_cos_impl_cuda(x):
      >>>     return torch.from_numpy(np.cos(x.cpu().numpy())).to(x.device)
      >>>
      >>> x = torch.randn(3)
      >>> numpy_cos(x)  # calls numpy_cos_impl_cpu
      >>>
      >>> x_cuda = x.cuda()
      >>> numpy_cos(x)  # calls numpy_cos_impl_cuda
docstr_tok: ["Register","an","implementation","for","a","device","type","for","this","CustomOp","object",".","WARNING",":","if","you","'re","a","user",",","please","do","not","use","this","directly","(","instead","use","the","torch._custom_ops","APIs",")",".","Also","please","see","the","following","for","a","detailed","guide","on","custom","ops",".","https",":","\/\/docs.google.com\/document\/d\/1aGWtgxV3HppuxQAdddyPrs74_aEntpkYt9MalnCKnhk","If","the","CustomOp","is","passed","multiple","Tensor","inputs","with","different","device","types",",","it","will","dispatch","to","the","registered","implementation","for","the","highest","priority","device","type","among","those","present",".","The","supported","device","types",",","in","order","of","priority",",","are","{","'cuda","'",",","'cpu","'","}",".","This","API","is","used","as","a","decorator","(","see","examples",")",".","Arguments",":","device_types","(","str","or","Iterable","[","str","]",")",":","the","device","type","(","s",")","to","register","the","function","for",".","Examples",":",":",">",">",">","#","xdoctest",":","+REQUIRES","(","env",":","TORCH_DOCTEST_CUDA",")",">",">",">","import","numpy","as","np",">",">",">","from","torch","import","Tensor",">",">",">",">",">",">","@","custom_op","(","``","my_library",":",":numpy_cos","''",")",">",">",">","def","numpy_cos","(","x",":","Tensor",")","-",">","Tensor",":",">",">",">","...",">",">",">",">",">",">","#","Register","an","implementation","for","CPU","Tensors",">",">",">","@","numpy_cos.impl","(","'cpu","'",")",">",">",">","def","numpy_cos_impl_cpu","(","x",")",":",">",">",">","return","torch.from_numpy","(","np.cos","(","x.numpy","(",")",")",")",">",">",">",">",">",">","#","Register","an","implementation","for","CUDA","Tensors",">",">",">","@","numpy_cos.impl","(","'cuda","'",")",">",">",">","def","numpy_cos_impl_cuda","(","x",")",":",">",">",">","return","torch.from_numpy","(","np.cos","(","x.cpu","(",")",".numpy","(",")",")",")",".to","(","x.device",")",">",">",">",">",">",">","x","=","torch.randn","(","3",")",">",">",">","numpy_cos","(","x",")","#","calls","numpy_cos_impl_cpu",">",">",">",">",">",">","x_cuda","=","x.cuda","(",")",">",">",">","numpy_cos","(","x",")","#","calls","numpy_cos_impl_cuda"]
code: def impl(
      self,
      device_types: typing.Union[str, typing.Iterable[str]],
      _stacklevel=2,
  ) -> typing.Callable:
      r"""Register an implementation for a device type for this CustomOp object.
  
      WARNING: if you're a user, please do not use this directly
      (instead use the torch._custom_ops APIs).
      Also please see the following for a detailed guide on custom ops.
      https://docs.google.com/document/d/1aGWtgxV3HppuxQAdddyPrs74_aEntpkYt9MalnCKnhk
  
      If the CustomOp is passed multiple Tensor inputs with different device
      types, it will dispatch to the registered implementation for the highest
      priority device type among those present.
      The supported device types, in order of priority, are {'cuda', 'cpu'}.
  
      This API is used as a decorator (see examples).
  
      Arguments:
          device_types (str or Iterable[str]): the device type(s) to register the function for.
  
      Examples::
          >>> # xdoctest: +REQUIRES(env:TORCH_DOCTEST_CUDA)
          >>> import numpy as np
          >>> from torch import Tensor
          >>>
          >>> @custom_op("my_library::numpy_cos")
          >>> def numpy_cos(x: Tensor) -> Tensor:
          >>>     ...
          >>>
          >>> # Register an implementation for CPU Tensors
          >>> @numpy_cos.impl('cpu')
          >>> def numpy_cos_impl_cpu(x):
          >>>     return torch.from_numpy(np.cos(x.numpy()))
          >>>
          >>> # Register an implementation for CUDA Tensors
          >>> @numpy_cos.impl('cuda')
          >>> def numpy_cos_impl_cuda(x):
          >>>     return torch.from_numpy(np.cos(x.cpu().numpy())).to(x.device)
          >>>
          >>> x = torch.randn(3)
          >>> numpy_cos(x)  # calls numpy_cos_impl_cpu
          >>>
          >>> x_cuda = x.cuda()
          >>> numpy_cos(x)  # calls numpy_cos_impl_cuda
  
      """
      if isinstance(device_types, str):
          device_types = [device_types]
      for device_type in device_types:
          validate_device_type(device_type)
  
      def inner(f):
          for device_type in set(device_types):
              self._check_doesnt_have_library_impl(device_type)
              self._register_impl(
                  device_type, f, stacklevel=_stacklevel
              )
              dispatch_key = SUPPORTED_DEVICE_TYPE_TO_KEY[device_type]
              library.impl(self._lib, self._opname, dispatch_key)(f)
          return f
  
      return inner
  
imports: import dataclasses
  import functools
  import inspect
  import sys
  import typing
  import weakref
  from torchgen.model import FunctionSchema, OperatorName, SchemaKind, BaseType, ListType, BaseTy
  import torch
  import torch._C
  import torch.library
  from torch._library.abstract_impl import AbstractImplCtx
  from torch.library import get_ctx
  from .autograd import autograd_kernel_indirection, construct_autograd_kernel
label_desc: Use image node_id 9 for calling the CustomOp obj's underlying member method code with example usage: obj.impl(device_types, _stacklevel) and returns: inner, f