# mypy: allow-untyped-defsr"""This package introduces support for the XPU backend, specifically tailored forIntel GPU optimization.This package is lazily initialized, so you can always import it, and use:func:`is_available()` to determine if your system supports XPU."""importthreadingimporttracebackfromfunctoolsimportlru_cachefromtypingimportAny,Callable,Dict,List,Optional,Tuple,Unionimporttorchimporttorch._Cfromtorchimportdeviceas_devicefromtorch._utilsimport_dummy_type,_LazySeedTrackerfrom._utilsimport_get_device_indexfrom.streamsimportEvent,Stream_initialized=False_tls=threading.local()_initialization_lock=threading.Lock()_queued_calls:List[Tuple[Callable[[],None],List[str]]]=[]# don't invoke these until initialization occurs_is_in_bad_fork=getattr(torch._C,"_xpu_isInBadFork",lambda:False)_device_t=Union[_device,str,int,None]_lazy_seed_tracker=_LazySeedTracker()default_generators:Tuple[torch._C.Generator]=()# type: ignore[assignment]def_is_compiled()->bool:r"""Return true if compile with XPU support."""returntorch._C._has_xpuif_is_compiled():_XpuDeviceProperties=torch._C._XpuDeviceProperties_exchange_device=torch._C._xpu_exchangeDevice_maybe_exchange_device=torch._C._xpu_maybeExchangeDeviceelse:# Define dummy if PyTorch was compiled without XPU_XpuDeviceProperties=_dummy_type("_XpuDeviceProperties")# type: ignore[assignment, misc]def_exchange_device(device:int)->int:raiseNotImplementedError("PyTorch was compiled without XPU support")def_maybe_exchange_device(device:int)->int:raiseNotImplementedError("PyTorch was compiled without XPU support")
[docs]@lru_cache(maxsize=1)defdevice_count()->int:r"""Return the number of XPU device available."""ifnot_is_compiled():return0returntorch._C._xpu_getDeviceCount()
[docs]defis_available()->bool:r"""Return a bool indicating if XPU is currently available."""# This function nerver throws.returndevice_count()>0
defis_bf16_supported():r"""Return a bool indicating if the current XPU device supports dtype bfloat16."""returnTrue
[docs]defis_initialized():r"""Return whether PyTorch's XPU state has been initialized."""return_initializedandnot_is_in_bad_fork()
def_lazy_call(callable,**kwargs):ifis_initialized():callable()else:global_lazy_seed_trackerifkwargs.get("seed_all",False):_lazy_seed_tracker.queue_seed_all(callable,traceback.format_stack())elifkwargs.get("seed",False):_lazy_seed_tracker.queue_seed(callable,traceback.format_stack())else:# Don't store the actual traceback to avoid memory cycle_queued_calls.append((callable,traceback.format_stack()))
[docs]definit():r"""Initialize PyTorch's XPU state. This is a Python API about lazy initialization that avoids initializing XPU until the first time it is accessed. Does nothing if the XPU state is already initialized. """_lazy_init()
def_lazy_init():global_initialized,_queued_callsifis_initialized()orhasattr(_tls,"is_initializing"):returnwith_initialization_lock:# This test was was protected via GIL. Double-check whether XPU has# already been initialized.ifis_initialized():return# Stop promptly upon encountering a bad fork error.if_is_in_bad_fork():raiseRuntimeError("Cannot re-initialize XPU in forked subprocess. To use XPU with ""multiprocessing, you must use the 'spawn' start method")ifnot_is_compiled():raiseAssertionError("Torch not compiled with XPU enabled")# This function inits XPU backend and detects bad fork processing.torch._C._xpu_init()# Some of the queued calls may reentrantly call _lazy_init(); We need to# just return without initializing in that case._tls.is_initializing=Trueforcallsin_lazy_seed_tracker.get_calls():ifcalls:_queued_calls.append(calls)try:forqueued_call,orig_tracebackin_queued_calls:try:queued_call()exceptExceptionase:msg=(f"XPU call failed lazily at initialization with error: {str(e)}\n\n"f"XPU call was originally invoked at:\n\n{''.join(orig_traceback)}")raiseException(msg)frome# noqa: TRY002finally:delattr(_tls,"is_initializing")_initialized=Trueclass_DeviceGuard:def__init__(self,index:int):self.idx=indexself.prev_idx=-1def__enter__(self):self.prev_idx=torch.xpu._exchange_device(self.idx)def__exit__(self,type:Any,value:Any,traceback:Any):self.idx=torch.xpu._maybe_exchange_device(self.prev_idx)returnFalse
[docs]classdevice:r"""Context-manager that changes the selected device. Args: device (torch.device or int or str): device index to select. It's a no-op if this argument is a negative integer or ``None``. """def__init__(self,device:Any):self.idx=_get_device_index(device,optional=True)self.prev_idx=-1def__enter__(self):self.prev_idx=torch.xpu._exchange_device(self.idx)def__exit__(self,type:Any,value:Any,traceback:Any):self.idx=torch.xpu._maybe_exchange_device(self.prev_idx)returnFalse
[docs]classdevice_of(device):r"""Context-manager that changes the current device to that of given object. You can use both tensors and storages as arguments. If a given object is not allocated on a XPU, this is a no-op. Args: obj (Tensor or Storage): object allocated on the selected device. """def__init__(self,obj):idx=obj.get_device()ifobj.is_xpuelse-1super().__init__(idx)
[docs]defset_device(device:_device_t)->None:r"""Set the current device. Args: device (torch.device or int or str): selected device. This function is a no-op if this argument is negative. """_lazy_init()device=_get_device_index(device)ifdevice>=0:torch._C._xpu_setDevice(device)
[docs]defget_device_name(device:Optional[_device_t]=None)->str:r"""Get the name of a device. Args: device (torch.device or int or str, optional): device for which to return the name. This function is a no-op if this argument is a negative integer. It uses the current device, given by :func:`~torch.xpu.current_device`, if :attr:`device` is ``None`` (default). Returns: str: the name of the device """returnget_device_properties(device).name
[docs]@lru_cache(None)defget_device_capability(device:Optional[_device_t]=None)->Dict[str,Any]:r"""Get the xpu capability of a device. Args: device (torch.device or int or str, optional): device for which to return the device capability. This function is a no-op if this argument is a negative integer. It uses the current device, given by :func:`~torch.xpu.current_device`, if :attr:`device` is ``None`` (default). Returns: Dict[str, Any]: the xpu capability dictionary of the device """props=get_device_properties(device)return{prop:getattr(props,prop)forpropindir(props)ifnotprop.startswith("__")}
[docs]defget_device_properties(device:Optional[_device_t]=None)->_XpuDeviceProperties:r"""Get the properties of a device. Args: device (torch.device or int or str): device for which to return the properties of the device. Returns: _XpuDeviceProperties: the properties of the device """_lazy_init()device=_get_device_index(device,optional=True)ifdevice<0ordevice>=device_count():raiseAssertionError("Invalid device index")return_get_device_properties(device)# type: ignore[name-defined] # noqa: F821
[docs]defcurrent_device()->int:r"""Return the index of a currently selected device."""_lazy_init()returntorch._C._xpu_getDevice()
def_get_device(device:Union[int,str,torch.device])->torch.device:r"""Return the torch.device type object from the passed in device. Args: device (torch.device or int or str): selected device. """ifisinstance(device,str):device=torch.device(device)elifisinstance(device,int):device=torch.device("xpu",device)returndevice
[docs]classStreamContext:r"""Context-manager that selects a given stream. All XPU kernels queued within its context will be enqueued on a selected stream. Args: Stream (Stream): selected stream. This manager is a no-op if it's ``None``. .. note:: Streams are per-device. """cur_stream:Optional["torch.xpu.Stream"]def__init__(self,stream:Optional["torch.xpu.Stream"]):self.stream=streamself.idx=_get_device_index(None,True)ifself.idxisNone:self.idx=-1def__enter__(self):cur_stream=self.streamifcur_streamisNoneorself.idx==-1:returnself.src_prev_stream=torch.xpu.current_stream(None)# If the stream is not on the current device, then set the current stream on the deviceifself.src_prev_stream.device!=cur_stream.device:withdevice(cur_stream.device):self.dst_prev_stream=torch.xpu.current_stream(cur_stream.device)torch.xpu.set_stream(cur_stream)def__exit__(self,type:Any,value:Any,traceback:Any):cur_stream=self.streamifcur_streamisNoneorself.idx==-1:return# Reset the stream on the original device and destination deviceifself.src_prev_stream.device!=cur_stream.device:torch.xpu.set_stream(self.dst_prev_stream)torch.xpu.set_stream(self.src_prev_stream)
[docs]defstream(stream:Optional["torch.xpu.Stream"])->StreamContext:r"""Wrap around the Context-manager StreamContext that selects a given stream. Arguments: stream (Stream): selected stream. This manager is a no-op if it's ``None``. """returnStreamContext(stream)
def_set_stream_by_id(stream_id,device_index,device_type):r"""set stream specified by the stream id, device index and device type Args: stream_id (int): not visible to the user, used to assigned to the specific stream. device_index (int): selected device index. device_type (int): selected device type. """torch._C._xpu_setStream(stream_id=stream_id,device_index=device_index,device_type=device_type,)
[docs]defset_stream(stream:Stream):r"""Set the current stream.This is a wrapper API to set the stream. Usage of this function is discouraged in favor of the ``stream`` context manager. Args: stream (Stream): selected stream. This function is a no-op if this argument is ``None``. """ifstreamisNone:return_lazy_init()_set_stream_by_id(stream_id=stream.stream_id,device_index=stream.device_index,device_type=stream.device_type,)
[docs]defcurrent_stream(device:Optional[_device_t]=None)->Stream:r"""Return the currently selected :class:`Stream` for a given device. Args: device (torch.device or int, optional): selected device. Returns the currently selected :class:`Stream` for the current device, given by :func:`~torch.xpu.current_device`, if :attr:`device` is ``None`` (default). """_lazy_init()streamdata=torch._C._xpu_getCurrentStream(_get_device_index(device,optional=True))returnStream(stream_id=streamdata[0],device_index=streamdata[1],device_type=streamdata[2])
[docs]defsynchronize(device:_device_t=None)->None:r"""Wait for all kernels in all streams on a XPU device to complete. Args: device (torch.device or int, optional): device for which to synchronize. It uses the current device, given by :func:`~torch.xpu.current_device`, if :attr:`device` is ``None`` (default). """_lazy_init()device=_get_device_index(device,optional=True)returntorch._C._xpu_synchronize(device)
def_get_generator(device:torch.device)->torch._C.Generator:r"""Return the XPU Generator object for the given device. Args: device (torch.device): selected device. """idx=device.indexifidxisNone:idx=current_device()returntorch.xpu.default_generators[idx]def_set_rng_state_offset(offset:int,device:Union[int,str,torch.device]="xpu")->None:r"""Set the random number generator state offset of the specified GPU. Args: offset (int): The desired offset device (torch.device or int, optional): The device to set the RNG state. Default: ``'xpu'`` (i.e., ``torch.device('xpu')``, the current XPU device). """final_device=_get_device(device)defcb():default_generator=_get_generator(final_device)default_generator.set_offset(offset)_lazy_call(cb)def_get_rng_state_offset(device:Union[int,str,torch.device]="xpu")->int:r"""Return the random number generator state offset of the specified GPU. Args: device (torch.device or int, optional): The device to return the RNG state offset of. Default: ``'xpu'`` (i.e., ``torch.device('xpu')``, the current XPU device). .. warning:: This function eagerly initializes XPU. """_lazy_init()final_device=_get_device(device)default_generator=_get_generator(final_device)returndefault_generator.get_offset()# import here to avoid circular importfrom.memoryimport(empty_cache,max_memory_allocated,max_memory_reserved,memory_allocated,memory_reserved,memory_stats,memory_stats_as_nested_dict,reset_accumulated_memory_stats,reset_peak_memory_stats,)from.randomimport(get_rng_state,get_rng_state_all,initial_seed,manual_seed,manual_seed_all,seed,seed_all,set_rng_state,set_rng_state_all,)__all__=["Event","Stream","StreamContext","current_device","current_stream","default_generators","device","device_of","device_count","empty_cache","get_device_capability","get_device_name","get_device_properties","get_rng_state","get_rng_state_all","get_stream","init","initial_seed","is_available","is_bf16_supported","is_initialized","manual_seed","manual_seed_all","max_memory_allocated","max_memory_reserved","memory_allocated","memory_reserved","memory_stats","memory_stats_as_nested_dict","reset_accumulated_memory_stats","reset_peak_memory_stats","seed","seed_all","set_device","set_rng_state","set_rng_state_all","set_stream","stream","streams","synchronize",]
Docs
Access comprehensive developer documentation for PyTorch
To analyze traffic and optimize your experience, we serve cookies on this site. By clicking or navigating, you agree to allow our usage of cookies. As the current maintainers of this site, Facebook’s Cookies Policy applies. Learn more, including about available controls: Cookies Policy.