| | import contextlib
|
| | import importlib
|
| | import torch
|
| | import intel_extension_for_pytorch as ipex
|
| |
|
| |
|
| |
|
| |
|
| | class CondFunc:
|
| | def __new__(cls, orig_func, sub_func, cond_func):
|
| | self = super(CondFunc, cls).__new__(cls)
|
| | if isinstance(orig_func, str):
|
| | func_path = orig_func.split(".")
|
| | for i in range(len(func_path) - 1, -1, -1):
|
| | try:
|
| | resolved_obj = importlib.import_module(".".join(func_path[:i]))
|
| | break
|
| | except ImportError:
|
| | pass
|
| | for attr_name in func_path[i:-1]:
|
| | resolved_obj = getattr(resolved_obj, attr_name)
|
| | orig_func = getattr(resolved_obj, func_path[-1])
|
| | setattr(
|
| | resolved_obj,
|
| | func_path[-1],
|
| | lambda *args, **kwargs: self(*args, **kwargs),
|
| | )
|
| | self.__init__(orig_func, sub_func, cond_func)
|
| | return lambda *args, **kwargs: self(*args, **kwargs)
|
| |
|
| | def __init__(self, orig_func, sub_func, cond_func):
|
| | self.__orig_func = orig_func
|
| | self.__sub_func = sub_func
|
| | self.__cond_func = cond_func
|
| |
|
| | def __call__(self, *args, **kwargs):
|
| | if not self.__cond_func or self.__cond_func(self.__orig_func, *args, **kwargs):
|
| | return self.__sub_func(self.__orig_func, *args, **kwargs)
|
| | else:
|
| | return self.__orig_func(*args, **kwargs)
|
| |
|
| |
|
| | _utils = torch.utils.data._utils
|
| |
|
| |
|
| | def _shutdown_workers(self):
|
| | if (
|
| | torch.utils.data._utils is None
|
| | or torch.utils.data._utils.python_exit_status is True
|
| | or torch.utils.data._utils.python_exit_status is None
|
| | ):
|
| | return
|
| | if hasattr(self, "_shutdown") and not self._shutdown:
|
| | self._shutdown = True
|
| | try:
|
| | if hasattr(self, "_pin_memory_thread"):
|
| | self._pin_memory_thread_done_event.set()
|
| | self._worker_result_queue.put((None, None))
|
| | self._pin_memory_thread.join()
|
| | self._worker_result_queue.cancel_join_thread()
|
| | self._worker_result_queue.close()
|
| | self._workers_done_event.set()
|
| | for worker_id in range(len(self._workers)):
|
| | if self._persistent_workers or self._workers_status[worker_id]:
|
| | self._mark_worker_as_unavailable(worker_id, shutdown=True)
|
| | for w in self._workers:
|
| | w.join(timeout=torch.utils.data._utils.MP_STATUS_CHECK_INTERVAL)
|
| | for q in self._index_queues:
|
| | q.cancel_join_thread()
|
| | q.close()
|
| | finally:
|
| | if self._worker_pids_set:
|
| | torch.utils.data._utils.signal_handling._remove_worker_pids(id(self))
|
| | self._worker_pids_set = False
|
| | for w in self._workers:
|
| | if w.is_alive():
|
| | w.terminate()
|
| |
|
| |
|
| | class DummyDataParallel(
|
| | torch.nn.Module
|
| | ):
|
| | def __new__(
|
| | cls, module, device_ids=None, output_device=None, dim=0
|
| | ):
|
| | if isinstance(device_ids, list) and len(device_ids) > 1:
|
| | print("IPEX backend doesn't support DataParallel on multiple XPU devices")
|
| | return module.to("xpu")
|
| |
|
| |
|
| | def return_null_context(*args, **kwargs):
|
| | return contextlib.nullcontext()
|
| |
|
| |
|
| | def check_device(device):
|
| | return bool(
|
| | (isinstance(device, torch.device) and device.type == "cuda")
|
| | or (isinstance(device, str) and "cuda" in device)
|
| | or isinstance(device, int)
|
| | )
|
| |
|
| |
|
| | def return_xpu(device):
|
| | return (
|
| | f"xpu:{device[-1]}"
|
| | if isinstance(device, str) and ":" in device
|
| | else (
|
| | f"xpu:{device}"
|
| | if isinstance(device, int)
|
| | else torch.device("xpu") if isinstance(device, torch.device) else "xpu"
|
| | )
|
| | )
|
| |
|
| |
|
| | def ipex_no_cuda(orig_func, *args, **kwargs):
|
| | torch.cuda.is_available = lambda: False
|
| | orig_func(*args, **kwargs)
|
| | torch.cuda.is_available = torch.xpu.is_available
|
| |
|
| |
|
| | original_autocast = torch.autocast
|
| |
|
| |
|
| | def ipex_autocast(*args, **kwargs):
|
| | if len(args) > 0 and args[0] == "cuda":
|
| | return original_autocast("xpu", *args[1:], **kwargs)
|
| | else:
|
| | return original_autocast(*args, **kwargs)
|
| |
|
| |
|
| | original_torch_cat = torch.cat
|
| |
|
| |
|
| | def torch_cat(tensor, *args, **kwargs):
|
| | if len(tensor) == 3 and (
|
| | tensor[0].dtype != tensor[1].dtype or tensor[2].dtype != tensor[1].dtype
|
| | ):
|
| | return original_torch_cat(
|
| | [tensor[0].to(tensor[1].dtype), tensor[1], tensor[2].to(tensor[1].dtype)],
|
| | *args,
|
| | **kwargs,
|
| | )
|
| | else:
|
| | return original_torch_cat(tensor, *args, **kwargs)
|
| |
|
| |
|
| | original_interpolate = torch.nn.functional.interpolate
|
| |
|
| |
|
| | def interpolate(
|
| | tensor,
|
| | size=None,
|
| | scale_factor=None,
|
| | mode="nearest",
|
| | align_corners=None,
|
| | recompute_scale_factor=None,
|
| | antialias=False,
|
| | ):
|
| | if antialias or align_corners is not None:
|
| | return_device = tensor.device
|
| | return_dtype = tensor.dtype
|
| | return original_interpolate(
|
| | tensor.to("cpu", dtype=torch.float32),
|
| | size=size,
|
| | scale_factor=scale_factor,
|
| | mode=mode,
|
| | align_corners=align_corners,
|
| | recompute_scale_factor=recompute_scale_factor,
|
| | antialias=antialias,
|
| | ).to(return_device, dtype=return_dtype)
|
| | else:
|
| | return original_interpolate(
|
| | tensor,
|
| | size=size,
|
| | scale_factor=scale_factor,
|
| | mode=mode,
|
| | align_corners=align_corners,
|
| | recompute_scale_factor=recompute_scale_factor,
|
| | antialias=antialias,
|
| | )
|
| |
|
| |
|
| | original_linalg_solve = torch.linalg.solve
|
| |
|
| |
|
| | def linalg_solve(A, B, *args, **kwargs):
|
| | if A.device != torch.device("cpu") or B.device != torch.device("cpu"):
|
| | return_device = A.device
|
| | return original_linalg_solve(A.to("cpu"), B.to("cpu"), *args, **kwargs).to(
|
| | return_device
|
| | )
|
| | else:
|
| | return original_linalg_solve(A, B, *args, **kwargs)
|
| |
|
| |
|
| | def ipex_hijacks():
|
| | CondFunc(
|
| | "torch.Tensor.to",
|
| | lambda orig_func, self, device=None, *args, **kwargs: orig_func(
|
| | self, return_xpu(device), *args, **kwargs
|
| | ),
|
| | lambda orig_func, self, device=None, *args, **kwargs: check_device(device),
|
| | )
|
| | CondFunc(
|
| | "torch.Tensor.cuda",
|
| | lambda orig_func, self, device=None, *args, **kwargs: orig_func(
|
| | self, return_xpu(device), *args, **kwargs
|
| | ),
|
| | lambda orig_func, self, device=None, *args, **kwargs: check_device(device),
|
| | )
|
| | CondFunc(
|
| | "torch.empty",
|
| | lambda orig_func, *args, device=None, **kwargs: orig_func(
|
| | *args, device=return_xpu(device), **kwargs
|
| | ),
|
| | lambda orig_func, *args, device=None, **kwargs: check_device(device),
|
| | )
|
| | CondFunc(
|
| | "torch.load",
|
| | lambda orig_func, *args, map_location=None, **kwargs: orig_func(
|
| | *args, return_xpu(map_location), **kwargs
|
| | ),
|
| | lambda orig_func, *args, map_location=None, **kwargs: map_location is None
|
| | or check_device(map_location),
|
| | )
|
| | CondFunc(
|
| | "torch.randn",
|
| | lambda orig_func, *args, device=None, **kwargs: orig_func(
|
| | *args, device=return_xpu(device), **kwargs
|
| | ),
|
| | lambda orig_func, *args, device=None, **kwargs: check_device(device),
|
| | )
|
| | CondFunc(
|
| | "torch.ones",
|
| | lambda orig_func, *args, device=None, **kwargs: orig_func(
|
| | *args, device=return_xpu(device), **kwargs
|
| | ),
|
| | lambda orig_func, *args, device=None, **kwargs: check_device(device),
|
| | )
|
| | CondFunc(
|
| | "torch.zeros",
|
| | lambda orig_func, *args, device=None, **kwargs: orig_func(
|
| | *args, device=return_xpu(device), **kwargs
|
| | ),
|
| | lambda orig_func, *args, device=None, **kwargs: check_device(device),
|
| | )
|
| | CondFunc(
|
| | "torch.tensor",
|
| | lambda orig_func, *args, device=None, **kwargs: orig_func(
|
| | *args, device=return_xpu(device), **kwargs
|
| | ),
|
| | lambda orig_func, *args, device=None, **kwargs: check_device(device),
|
| | )
|
| | CondFunc(
|
| | "torch.linspace",
|
| | lambda orig_func, *args, device=None, **kwargs: orig_func(
|
| | *args, device=return_xpu(device), **kwargs
|
| | ),
|
| | lambda orig_func, *args, device=None, **kwargs: check_device(device),
|
| | )
|
| |
|
| | CondFunc(
|
| | "torch.Generator",
|
| | lambda orig_func, device=None: torch.xpu.Generator(device),
|
| | lambda orig_func, device=None: device is not None
|
| | and device != torch.device("cpu")
|
| | and device != "cpu",
|
| | )
|
| |
|
| | CondFunc(
|
| | "torch.batch_norm",
|
| | lambda orig_func, input, weight, bias, *args, **kwargs: orig_func(
|
| | input,
|
| | (
|
| | weight
|
| | if weight is not None
|
| | else torch.ones(input.size()[1], device=input.device)
|
| | ),
|
| | (
|
| | bias
|
| | if bias is not None
|
| | else torch.zeros(input.size()[1], device=input.device)
|
| | ),
|
| | *args,
|
| | **kwargs,
|
| | ),
|
| | lambda orig_func, input, *args, **kwargs: input.device != torch.device("cpu"),
|
| | )
|
| | CondFunc(
|
| | "torch.instance_norm",
|
| | lambda orig_func, input, weight, bias, *args, **kwargs: orig_func(
|
| | input,
|
| | (
|
| | weight
|
| | if weight is not None
|
| | else torch.ones(input.size()[1], device=input.device)
|
| | ),
|
| | (
|
| | bias
|
| | if bias is not None
|
| | else torch.zeros(input.size()[1], device=input.device)
|
| | ),
|
| | *args,
|
| | **kwargs,
|
| | ),
|
| | lambda orig_func, input, *args, **kwargs: input.device != torch.device("cpu"),
|
| | )
|
| |
|
| |
|
| | CondFunc(
|
| | "torch.nn.modules.GroupNorm.forward",
|
| | lambda orig_func, self, input: orig_func(
|
| | self, input.to(self.weight.data.dtype)
|
| | ),
|
| | lambda orig_func, self, input: input.dtype != self.weight.data.dtype,
|
| | )
|
| | CondFunc(
|
| | "torch.nn.modules.linear.Linear.forward",
|
| | lambda orig_func, self, input: orig_func(
|
| | self, input.to(self.weight.data.dtype)
|
| | ),
|
| | lambda orig_func, self, input: input.dtype != self.weight.data.dtype,
|
| | )
|
| | CondFunc(
|
| | "torch.nn.modules.conv.Conv2d.forward",
|
| | lambda orig_func, self, input: orig_func(
|
| | self, input.to(self.weight.data.dtype)
|
| | ),
|
| | lambda orig_func, self, input: input.dtype != self.weight.data.dtype,
|
| | )
|
| | CondFunc(
|
| | "torch.nn.functional.layer_norm",
|
| | lambda orig_func, input, normalized_shape=None, weight=None, *args, **kwargs: orig_func(
|
| | input.to(weight.data.dtype), normalized_shape, weight, *args, **kwargs
|
| | ),
|
| | lambda orig_func, input, normalized_shape=None, weight=None, *args, **kwargs: weight
|
| | is not None
|
| | and input.dtype != weight.data.dtype,
|
| | )
|
| |
|
| |
|
| | if not torch.xpu.has_fp64_dtype():
|
| | CondFunc(
|
| | "torch.from_numpy",
|
| | lambda orig_func, ndarray: orig_func(ndarray.astype("float32")),
|
| | lambda orig_func, ndarray: ndarray.dtype == float,
|
| | )
|
| |
|
| |
|
| | CondFunc(
|
| | "torch.utils.data.dataloader._BaseDataLoaderIter.__init__",
|
| | lambda orig_func, *args, **kwargs: ipex_no_cuda(orig_func, *args, **kwargs),
|
| | lambda orig_func, *args, **kwargs: True,
|
| | )
|
| |
|
| |
|
| | torch.utils.data.dataloader._MultiProcessingDataLoaderIter._shutdown_workers = (
|
| | _shutdown_workers
|
| | )
|
| | torch.nn.DataParallel = DummyDataParallel
|
| | torch.autocast = ipex_autocast
|
| | torch.cat = torch_cat
|
| | torch.linalg.solve = linalg_solve
|
| | torch.nn.functional.interpolate = interpolate
|
| | torch.backends.cuda.sdp_kernel = return_null_context
|
| |
|