remove directml

Signed-off-by: Vladimir Mandic <mandic00@live.com>
This commit is contained in:
Vladimir Mandic
2026-08-10 13:43:45 +02:00
parent a5df015f5f
commit 6aa5b45b80
45 changed files with 35 additions and 1091 deletions
+1
View File
@@ -20,6 +20,7 @@
- **Server**
- update handlers for all authenticated workflows
- nunchaku-lite support for `torch==2.13`
- remove DirectML support: latest release was over 2 years ago and is not compatible with modern frameworks
- **Fixes**
- init hf env variables before gradio load
- lora skip init and rebuild offload state
-1
View File
@@ -28,7 +28,6 @@
- JSON image metadata
- Expand custom VAE support
- Refactor: remove obsolete code:
- Remove `directml`
- Remove `olive-ai`
- Integrate natural language image search
- [ImageDB](https://github.com/vladmandic/imagedb)
+2 -2
View File
@@ -743,13 +743,13 @@ def fp8_failure_is_capability(detail):
def print_environment(fp8_result, prep_status, prep_detail, weight_dequant_result=None):
device = torch.device(torch_device)
capability = torch_device_module.get_device_capability(device)
# backend runtime versions (cuda/cudnn/driver, hip, ipex, openvino, directml) so a shared
# backend runtime versions (cuda/cudnn/driver, hip, ipex, openvino) so a shared
# report identifies the stack without inferring it from the torch version string
try:
gpu_info = devices.get_gpu_info() or {}
except Exception:
gpu_info = {}
runtime_versions = {key: gpu_info[key] for key in ("cuda", "hip", "cudnn", "driver", "ipex", "openvino", "directml") if gpu_info.get(key)}
runtime_versions = {key: gpu_info[key] for key in ("cuda", "hip", "cudnn", "driver", "ipex", "openvino") if gpu_info.get(key)}
runtime_line = f"python: {sys.version.split()[0]} ({sys.platform}) backend: {getattr(devices, 'backend', 'unknown')}"
if runtime_versions:
runtime_line += " " + " ".join(f"{key}: {value}" for key, value in runtime_versions.items())
+22 -63
View File
@@ -54,7 +54,6 @@ args = Dot({
'skip_requirements': False,
'skip_git': False,
'skip_torch': False,
'use_directml': False,
'use_ipex': False,
'use_cuda': False,
'use_rocm': False,
@@ -586,7 +585,7 @@ def check_diffusers():
if args.skip_all:
return
target_commit = "6f2010e8bbe61fd2a81a659b858e298edcba8fab" # diffusers commit hash == 0.40.0.dev0 == 08-04-2026
# if args.use_rocm or args.use_zluda or args.use_directml:
# if args.use_rocm or args.use_zluda:
# sha = '043ab2520f6a19fce78e6e060a68dbc947edb9f9' # lock diffusers versions for now
pkg = package_spec('diffusers')
parts = pkg.version.split('.') if pkg is not None else []
@@ -616,36 +615,21 @@ def check_transformers():
# target_commit = '753d61104116eefc8ffc977327b441ee0c8d599f' # transformers commit hash == 4.57.6
# target_commit = "cf8572d34e39818e42dbf220701fbd3eb5b5a82a" # transformers commit hash == 5.14.0.dev0 == 08-04-2026
target_commit = "b70d02fc724d04c916832ca4ead03ff05e8fb1ee" # transformers commit hash == 5.13.0.dev0 == 07-03-2026
if args.use_directml:
target_transformers = '4.52.4'
target_tokenizers = '0.21.4'
else:
# target_transformers = '4.57.6'
target_transformers = None
target_tokenizers = '0.22.2'
if target_transformers is not None:
# Pinned release version (e.g. DirectML)
if args.reinstall or (pkg_transformers is None) or ((pkg_transformers.version != target_transformers) or (pkg_tokenizers is None) or ((pkg_tokenizers.version != target_tokenizers) and (not args.experimental))):
if pkg_transformers is None:
log.info(f'Install: package="transformers" version={target_transformers}')
else:
log.info(f'Update: package="transformers" current={pkg_transformers.version} target={target_transformers}')
pip('uninstall --yes transformers', ignore=True, quiet=True)
pip(f'install tokenizers=={target_tokenizers}', ignore=False, quiet=True)
pip(f'install transformers=={target_transformers}', ignore=False, quiet=True)
else:
# Git commit-pinned version
current = package_commit(pkg_transformers)
if args.reinstall or (pkg_transformers is None) or (pkg_transformers.version.startswith('4')) or (current != target_commit):
if pkg_transformers is None:
log.info(f'Install: package="transformers" commit={target_commit}')
else:
log.info(f'Update: package="transformers" current={pkg_transformers.version} commit={current} target={target_commit}')
pip('uninstall --yes transformers', ignore=True, quiet=True)
pip(f'install tokenizers=={target_tokenizers}', ignore=False, quiet=True)
pip(f'install git+https://github.com/huggingface/transformers@{target_commit}', ignore=False, quiet=True)
global transformers_commit # pylint: disable=global-statement
transformers_commit = target_commit
target_tokenizers = '0.22.2'
# Git commit-pinned version
current = package_commit(pkg_transformers)
if args.reinstall or (pkg_transformers is None) or (pkg_transformers.version.startswith('4')) or (current != target_commit):
if pkg_transformers is None:
log.info(f'Install: package="transformers" commit={target_commit}')
else:
log.info(f'Update: package="transformers" current={pkg_transformers.version} commit={current} target={target_commit}')
pip('uninstall --yes transformers', ignore=True, quiet=True)
pip(f'install tokenizers=={target_tokenizers}', ignore=False, quiet=True)
pip(f'install git+https://github.com/huggingface/transformers@{target_commit}', ignore=False, quiet=True)
global transformers_commit # pylint: disable=global-statement
transformers_commit = target_commit
if args.reinstall or (pkg_tokenizers is None) or (pkg_tokenizers.version != target_tokenizers):
pip(f'install tokenizers=={target_tokenizers}', ignore=False, quiet=True)
ts('transformers', t_start)
@@ -924,20 +908,17 @@ def check_torch():
if args.profile:
pr = cProfile.Profile()
pr.enable()
allow_cuda = not (args.use_rocm or args.use_directml or args.use_ipex or args.use_openvino)
allow_rocm = not (args.use_cuda or args.use_directml or args.use_ipex or args.use_openvino)
allow_ipex = not (args.use_cuda or args.use_rocm or args.use_directml or args.use_openvino)
allow_directml = not (args.use_cuda or args.use_rocm or args.use_ipex or args.use_openvino)
allow_openvino = not (args.use_cuda or args.use_rocm or args.use_ipex or args.use_directml)
log.debug(f'Torch overrides: cuda={args.use_cuda} rocm={args.use_rocm} ipex={args.use_ipex} directml={args.use_directml} openvino={args.use_openvino} zluda={args.use_zluda}')
# log.debug(f'Torch allowed: cuda={allow_cuda} rocm={allow_rocm} ipex={allow_ipex} diml={allow_directml} openvino={allow_openvino}')
allow_cuda = not (args.use_rocm or args.use_ipex or args.use_openvino)
allow_rocm = not (args.use_cuda or args.use_ipex or args.use_openvino)
allow_ipex = not (args.use_cuda or args.use_rocm or args.use_openvino)
allow_openvino = not (args.use_cuda or args.use_rocm or args.use_ipex)
log.debug(f'Torch overrides: cuda={args.use_cuda} rocm={args.use_rocm} ipex={args.use_ipex} openvino={args.use_openvino} zluda={args.use_zluda}')
# log.debug(f'Torch allowed: cuda={allow_cuda} rocm={allow_rocm} ipex={allow_ipex} openvino={allow_openvino}')
torch_command = os.environ.get('TORCH_COMMAND', '')
if sys.platform != 'win32':
if args.use_zluda:
log.error('ZLUDA is only supported on Windows')
if args.use_directml:
log.error('DirectML is only supported on Windows')
if torch_command != '':
is_cuda_available = False
@@ -967,15 +948,8 @@ def check_torch():
elif is_ipex_available:
torch_command = install_ipex()
else:
machine = platform.machine()
if sys.platform == 'darwin':
torch_command = os.environ.get('TORCH_COMMAND', 'torch torchvision')
elif allow_directml and args.use_directml and ('arm' not in machine and 'aarch' not in machine):
log.info('DirectML: selected')
torch_command = os.environ.get('TORCH_COMMAND', 'torch==2.4.1 torchvision torch-directml==0.2.4.dev240913')
if 'torch' in torch_command and not args.version:
install(torch_command, 'torch torchvision')
install('onnxruntime-directml', 'onnxruntime-directml', ignore=True)
else:
log.warning('Torch: CPU-only version installed')
torch_command = os.environ.get('TORCH_COMMAND', 'torch torchvision')
@@ -1067,21 +1041,6 @@ def check_torch():
except Exception as e:
log.error(f'Torch: type=cuda/rocm {e}')
if args.use_directml and allow_directml:
try:
import torch_directml # pylint: disable=import-error
dml_ver = package_version("torch-directml")
log.warning(f'Torch backend: DirectML ({dml_ver})')
log.warning('DirectML: end-of-life')
for i in range(0, torch_directml.device_count()):
gpu = {
'gpu': torch_directml.device_name(i),
}
gpu_info.append(gpu)
log.info(f'Torch detected: {gpu}')
except Exception as e:
log.warning(f"Torch: type=directml {e}")
except Exception as e:
log.error(f'Torch cannot load: {e}')
if not args.ignore:
-1
View File
@@ -37,7 +37,6 @@ def add_compute_args(p):
p.add_argument("--use-rocm", default=env_flag("SD_USEROCM", False), action='store_true', help="Force use AMD ROCm backend, default: %(default)s")
p.add_argument('--use-zluda', default=env_flag("SD_USEZLUDA", False), action='store_true', help="Force use ZLUDA, AMD GPUs only, default: %(default)s")
p.add_argument("--use-openvino", default=env_flag("SD_USEOPENVINO", False), action='store_true', help="Use Intel OpenVINO backend, default: %(default)s")
p.add_argument('--use-directml', default=env_flag("SD_USEDIRECTML", False), action='store_true', help="Use DirectML if no compatible GPU is detected, default: %(default)s")
p.add_argument("--use-xformers", default=env_flag("SD_USEXFORMERS", False), action='store_true', help="Force use xFormers cross-optimization, default: %(default)s")
p.add_argument("--use-nightly", default=env_flag("SD_USENIGHTLY", False), action='store_true', help="Force use nightly torch builds, default: %(default)s")
p.add_argument("--no-half", default=env_flag("SD_NOHALF", False), action='store_true', help="Do not switch the model to 16-bit float, default: %(default)s")
+4 -22
View File
@@ -79,8 +79,6 @@ def get_backend(shared_cmd_opts):
args = shared_cmd_opts
if args.use_openvino:
name = 'openvino'
elif args.use_directml:
name = 'directml'
elif has_xpu():
name = 'ipex'
elif has_zluda():
@@ -131,11 +129,6 @@ def get_gpu_info():
'devices': devices,
'openvino': get_package_version("openvino"),
}
elif backend == 'directml':
return {
'device': f'{torch.cuda.get_device_name(torch.cuda.current_device())} n={torch.cuda.device_count()}',
'directml': get_package_version("torch-directml"),
}
else:
return {}
except Exception:
@@ -176,10 +169,6 @@ def get_cuda_device_string():
if cmd_opts.device_id is not None:
return f"xpu:{cmd_opts.device_id}"
return "xpu"
elif backend == 'directml' and torch.dml.is_available():
if cmd_opts.device_id is not None:
return f"privateuseone:{cmd_opts.device_id}"
return torch.dml.get_device_string(torch.dml.default_device().index)
else:
if cmd_opts.device_id is not None:
return f"cuda:{cmd_opts.device_id}"
@@ -189,7 +178,7 @@ def get_cuda_device_string():
def get_optimal_device_name():
if backend == 'openvino':
return "cpu"
if cuda_ok or backend == 'directml':
if cuda_ok:
return get_cuda_device_string()
if has_mps() and backend != 'openvino':
return "mps"
@@ -205,12 +194,9 @@ def torch_gc(force: bool = False, fast: bool = False, reason: str | None = None)
mem_dict = memstats.memory_stats()
gpu_dict = mem_dict.get('gpu', {})
ram_dict = mem_dict.get('ram', {})
oom = gpu_dict.get('oom', 0)
ram = ram_dict.get('used', 0)
if backend == "directml":
gpu = torch.cuda.memory_allocated() / (1 << 30)
else:
gpu = gpu_dict.get('used', 0)
oom = gpu_dict.get('oom', 0)
gpu = gpu_dict.get('used', 0)
used_gpu = round(100 * gpu / gpu_dict.get('total', 1)) if gpu_dict.get('total', 1) > 1 else 0
used_ram = round(100 * ram / ram_dict.get('total', 1)) if ram_dict.get('total', 1) > 1 else 0
return gpu, used_gpu, ram, used_ram, oom
@@ -374,7 +360,7 @@ def test_bf16():
if bf16_ok is not None:
return bf16_ok
if opts.cuda_dtype != 'BF16': # don't override if the user sets it
if sys.platform == "darwin" or backend in {'directml', 'cpu'}: # override
if sys.platform == "darwin" or backend == 'cpu': # override
bf16_ok = False
return bf16_ok
elif backend == 'openvino':
@@ -676,8 +662,6 @@ def randn_without_seed(shape):
def autocast(disable=False):
if disable or dtype == torch.float32:
return contextlib.nullcontext()
if backend == 'directml':
return torch.dml.amp.autocast(dtype)
if cuda_ok:
return torch.autocast("cuda")
else:
@@ -687,8 +671,6 @@ def autocast(disable=False):
def without_autocast(disable=False):
if disable:
return contextlib.nullcontext()
if backend == 'directml':
return torch.dml.amp.autocast(enabled=False) if torch.is_autocast_enabled() else contextlib.nullcontext() # pylint: disable=unexpected-keyword-arg
if cuda_ok:
return torch.autocast("cuda", enabled=False) if torch.is_autocast_enabled() else contextlib.nullcontext()
else:
-6
View File
@@ -1,6 +0,0 @@
import torch
class Generator(torch.Generator):
def __init__(self, device: torch.device | None = None):
super().__init__("cpu")
-116
View File
@@ -1,116 +0,0 @@
import platform
from typing import NamedTuple
from collections.abc import Callable
import torch
from modules.logger import log
from modules.sd_hijack_utils import CondFunc
memory_providers = ["None", "atiadlxx (AMD only)"]
default_memory_provider = "None"
if platform.system() == "Windows":
memory_providers.append("Performance Counter")
default_memory_provider = "Performance Counter"
do_nothing = lambda: None # pylint: disable=unnecessary-lambda-assignment
do_nothing_with_self = lambda self: None # pylint: disable=unnecessary-lambda-assignment
def _set_memory_provider():
from modules.shared import opts, cmd_opts
if opts.directml_memory_provider == "Performance Counter":
from .backend import pdh_mem_get_info
from .memory import MemoryProvider
torch.dml.mem_get_info = pdh_mem_get_info
if torch.dml.memory_provider is not None:
del torch.dml.memory_provider
torch.dml.memory_provider = MemoryProvider()
elif opts.directml_memory_provider == "atiadlxx (AMD only)":
device_name = torch.dml.get_device_name(cmd_opts.device_id)
if "AMD" not in device_name and "Radeon" not in device_name:
log.warning(f"Memory stats provider is changed to None because the current device is not AMDGPU. Current Device: {device_name}")
opts.directml_memory_provider = "None"
_set_memory_provider()
return
from .backend import amd_mem_get_info
torch.dml.mem_get_info = amd_mem_get_info
else:
from .backend import mem_get_info
torch.dml.mem_get_info = mem_get_info
torch.cuda.mem_get_info = torch.dml.mem_get_info
def directml_init():
try:
from modules.dml.backend import DirectML # pylint: disable=ungrouped-imports
# Alternative of torch.cuda for DirectML.
torch.dml = DirectML
torch.cuda.is_available = lambda: False
torch.cuda.device = torch.dml.device
torch.cuda.device_count = torch.dml.device_count
torch.cuda.current_device = torch.dml.current_device
torch.cuda.get_device_name = torch.dml.get_device_name
torch.cuda.get_device_properties = torch.dml.get_device_properties
torch.cuda.empty_cache = do_nothing
torch.cuda.ipc_collect = do_nothing
torch.cuda.memory_stats = torch.dml.memory_stats
torch.cuda.mem_get_info = torch.dml.mem_get_info
torch.cuda.memory_allocated = torch.dml.memory_allocated
torch.cuda.max_memory_allocated = torch.dml.max_memory_allocated
torch.cuda.reset_peak_memory_stats = torch.dml.reset_peak_memory_stats
torch.cuda.utilization = lambda: 0
torch.Tensor.directml = lambda self: self.to(torch.dml.current_device())
except Exception as e:
log.error(f'DirectML initialization failed: {e}')
return False, e
return True, None
def directml_do_hijack():
import modules.dml.hijack # pylint: disable=unused-import
from modules.devices import device
CondFunc('torch.Generator',
lambda orig_func, device = None: orig_func("cpu"),
lambda orig_func, device = None: True)
if not torch.dml.has_float64_support(device):
torch.Tensor.__str__ = do_nothing_with_self
CondFunc('torch.from_numpy',
lambda orig_func, *args, **kwargs: orig_func(args[0].astype('float32')),
lambda *args, **kwargs: args[1].dtype == float)
_set_memory_provider()
class OverrideItem(NamedTuple):
value: str
condition: Callable | None
message: str | None
opts_override_table = {
"diffusers_generator_device": OverrideItem("CPU", None, "DirectML does not support torch Generator API"),
}
def directml_override_opts():
from modules import shared
if shared.cmd_opts.experimental:
return
count = 0
for key in opts_override_table:
item = opts_override_table[key]
if getattr(shared.opts, key) != item.value and (item.condition is None or item.condition(shared.opts)):
count += 1
setattr(shared.opts, key, item.value)
log.warning(f'Overriding: {key}={item.value} {item.message if item.message is not None else ""}')
if count > 0:
log.info(f'Options override: count={count}. If you want to keep them from overriding, run with --experimental argument.')
_set_memory_provider()
-1
View File
@@ -1 +0,0 @@
from .autocast_mode import autocast
-66
View File
@@ -1,66 +0,0 @@
import importlib
from typing import Any
import torch
ops = ["torch.Tensor.__matmul__", "torch.addbmm", "torch.addmm", "torch.addmv", "torch.addr", "torch.baddbmm", "torch.bmm", "torch.chain_matmul", "torch.linalg.multi_dot", "torch.nn.functional.conv1d", "torch.nn.functional.conv2d", "torch.nn.functional.conv3d", "torch.nn.functional.conv_transpose1d", "torch.nn.functional.conv_transpose2d", "torch.nn.functional.conv_transpose3d", "torch.nn.GRUCell", "torch.nn.functional.linear", "torch.nn.LSTMCell", "torch.matmul", "torch.mm", "torch.mv", "torch.prelu", "torch.nn.RNNCell", "torch.embedding"]
supported_cast_pairs = {
torch.float16: (torch.float32,),
torch.float32: (torch.float16,),
}
def forward(op, args: tuple, kwargs: dict):
if not torch.dml.is_autocast_enabled:
return op(*args, **kwargs)
args = list(map(cast, args))
for kwarg in kwargs:
kwargs[kwarg] = cast(kwargs[kwarg])
return op(*args, **kwargs)
def cast(tensor: torch.Tensor):
if not torch.is_tensor(tensor):
return tensor
dtype: torch.dtype = tensor.dtype
if dtype not in supported_cast_pairs or (torch.dml.autocast_gpu_dtype != dtype and torch.dml.autocast_gpu_dtype not in supported_cast_pairs[dtype]):
return tensor
return tensor.type(torch.dml.autocast_gpu_dtype)
def cond(op: str):
if isinstance(op, str):
func_path = op.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)
op = getattr(resolved_obj, func_path[-1])
setattr(resolved_obj, func_path[-1], lambda *args, **kwargs: forward(op, args, kwargs))
for o in ops:
cond(o)
class autocast:
prev: bool
fast_dtype: torch.dtype = torch.float16
prev_fast_dtype: torch.dtype
def __init__(self, dtype: torch.dtype | None = torch.float16):
self.fast_dtype = dtype
def __enter__(self):
self.prev = torch.dml.is_autocast_enabled
self.prev_fast_dtype = torch.dml.autocast_gpu_dtype
torch.dml.is_autocast_enabled = True
torch.dml.autocast_gpu_dtype = self.fast_dtype
def __exit__(self, exc_type: Any, exc_val: Any, exc_tb: Any):
torch.dml.is_autocast_enabled = self.prev
torch.dml.autocast_gpu_dtype = self.prev_fast_dtype
-80
View File
@@ -1,80 +0,0 @@
# pylint: disable=no-member,no-self-argument,no-method-argument
from collections.abc import Callable
import torch
import torch_directml # pylint: disable=import-error
import modules.dml.amp as amp
from .utils import rDevice, get_device
from .device import Device
from .Generator import Generator
from .device_properties import DeviceProperties
def amd_mem_get_info(device: rDevice | None=None) -> tuple[int, int]:
from .memory_amd import AMDMemoryProvider
return AMDMemoryProvider.mem_get_info(get_device(device).index)
def pdh_mem_get_info(device: rDevice | None=None) -> tuple[int, int]:
mem_info = DirectML.memory_provider.get_memory(get_device(device).index)
return (mem_info["total_committed"] - mem_info["dedicated_usage"], mem_info["total_committed"])
def mem_get_info(device: rDevice | None=None) -> tuple[int, int]: # pylint: disable=unused-argument
return (8589934592, 8589934592)
class DirectML:
amp = amp
device = Device
Generator = Generator
context_device: torch.device | None = None
is_autocast_enabled = False
autocast_gpu_dtype = torch.float16
memory_provider = None
def is_available() -> bool:
return torch_directml.is_available()
def is_directml_device(device: torch.device) -> bool:
return device.type == "privateuseone"
def has_float64_support(device: rDevice | None=None) -> bool:
return torch_directml.has_float64_support(get_device(device).index)
def device_count() -> int:
return torch_directml.device_count()
def current_device() -> torch.device:
return DirectML.context_device or DirectML.default_device()
def default_device() -> torch.device:
return torch_directml.device(torch_directml.default_device())
def get_device_string(device: rDevice | None=None) -> str:
return f"privateuseone:{get_device(device).index}"
def get_device_name(device: rDevice | None=None) -> str:
return torch_directml.device_name(get_device(device).index)
def get_device_properties(device: rDevice | None=None) -> DeviceProperties:
return DeviceProperties(get_device(device))
def memory_stats(device: rDevice | None=None):
return {
"num_ooms": 0,
"num_alloc_retries": 0,
}
mem_get_info: Callable = mem_get_info
def memory_allocated(device: rDevice | None=None) -> int:
return sum(torch_directml.gpu_memory(get_device(device).index)) * (1 << 20)
def max_memory_allocated(device: rDevice | None=None):
return DirectML.memory_allocated(device) # DirectML does not empty GPU memory
def reset_peak_memory_stats(device: rDevice | None=None):
return
-16
View File
@@ -1,16 +0,0 @@
import torch
from .utils import rDevice, get_device
class Device:
idx: int
def __enter__(self, device: rDevice | None=None):
torch.dml.context_device = get_device(device)
self.idx = torch.dml.context_device.index
def __init__(self, device: rDevice | None=None) -> torch.device: # pylint: disable=return-in-init
self.idx = get_device(device).index
def __exit__(self, t, v, tb):
torch.dml.context_device = None
-20
View File
@@ -1,20 +0,0 @@
import torch
class DeviceProperties:
type: str = "directml"
name: str
major: int = 0
minor: int = 0
total_memory: int
multi_processor_count: int = 1
def __init__(self, device: torch.device):
self.name = torch.dml.get_device_name(device)
self.total_memory = torch.dml.mem_get_info(device)[0]
def __str__(self):
return f"DeviceProperties(name='{self.name}', total_memory='{self.total_memory}')"
def __repr__(self):
return f"DeviceProperties(name='{self.name}', total_memory='{self.total_memory}')"
-4
View File
@@ -1,4 +0,0 @@
import modules.dml.hijack.torch
import modules.dml.hijack.realesrgan_model
import modules.dml.hijack.transformers
import modules.dml.hijack.tomesd
-67
View File
@@ -1,67 +0,0 @@
import math
import torch
from modules.postprocess.realesrgan_model_arch import RealESRGANer
from modules.logger import log
# DML Solution: Some of contents of output tensor turn to 0 after Extended Slices. Move it to cpu.
def tile_process(self):
batch, channel, height, width = self.img.shape
output_height = height * self.scale
output_width = width * self.scale
output_shape = (batch, channel, output_height, output_width)
# start with black image
self.output = self.img.new_zeros(output_shape)
tiles_x = math.ceil(width / self.tile_size)
tiles_y = math.ceil(height / self.tile_size)
# loop over all tiles
for y in range(tiles_y):
for x in range(tiles_x):
# extract tile from input image
ofs_x = x * self.tile_size
ofs_y = y * self.tile_size
# input tile area on total image
input_start_x = ofs_x
input_end_x = min(ofs_x + self.tile_size, width)
input_start_y = ofs_y
input_end_y = min(ofs_y + self.tile_size, height)
# input tile area on total image with padding
input_start_x_pad = max(input_start_x - self.tile_pad, 0)
input_end_x_pad = min(input_end_x + self.tile_pad, width)
input_start_y_pad = max(input_start_y - self.tile_pad, 0)
input_end_y_pad = min(input_end_y + self.tile_pad, height)
# input tile dimensions
input_tile_width = input_end_x - input_start_x
input_tile_height = input_end_y - input_start_y
_tile_idx = y * tiles_x + x + 1
input_tile = self.img[0:self.img.shape[0], 0:self.img.shape[1], input_start_y_pad:input_end_y_pad, input_start_x_pad:input_end_x_pad]
# upscale tile
try:
with torch.no_grad():
output_tile = self.model(input_tile)
except Exception as e:
log.error(f'Upscale error: type=R-ESRGAN {e}')
# output tile area on total image
output_start_x = input_start_x * self.scale
output_end_x = input_end_x * self.scale
output_start_y = input_start_y * self.scale
output_end_y = input_end_y * self.scale
# output tile area without padding
output_start_x_tile = (input_start_x - input_start_x_pad) * self.scale
output_end_x_tile = output_start_x_tile + input_tile_width * self.scale
output_start_y_tile = (input_start_y - input_start_y_pad) * self.scale
output_end_y_tile = output_start_y_tile + input_tile_height * self.scale
self.output = self.output.cpu()
# put tile into output image
self.output[0:self.output.shape[0], 0:self.output.shape[1], output_start_y:output_end_y, output_start_x:output_end_x] = output_tile.cpu()[0:output_tile.shape[0], 0:output_tile.shape[1], output_start_y_tile:output_end_y_tile, output_start_x_tile:output_end_x_tile]
self.output = self.output.to(output_tile.device)
RealESRGANer.tile_process = tile_process
-26
View File
@@ -1,26 +0,0 @@
import torch
from modules.dml.hijack.utils import catch_nan
def make_tome_block(block_class: type[torch.nn.Module]) -> type[torch.nn.Module]:
class ToMeBlock(block_class):
# Save for unpatching later
_parent = block_class
def _forward(self, x: torch.Tensor, context: torch.Tensor = None) -> torch.Tensor:
m_a, m_c, m_m, u_a, u_c, u_m = tomesd.patch.compute_merge(x, self._tome_info)
# This is where the meat of the computation happens
x = u_a(self.attn1(m_a(self.norm1(x)), context=context if self.disable_self_attn else None)) + x
x = catch_nan(lambda: (u_c(self.attn2(m_c(self.norm2(x)), context=context)) + x))
x = u_m(self.ff(m_m(self.norm3(x)))) + x
return x
return ToMeBlock
try:
import tomesd
tomesd.patch.make_tome_block = make_tome_block
except Exception:
pass
-35
View File
@@ -1,35 +0,0 @@
import torch
from modules.sd_hijack_utils import CondFunc
CondFunc('torchsde._brownian.brownian_interval._randn', lambda _, size, dtype, device, seed: torch.randn(size, dtype=dtype, device=torch.device("cpu"), generator=torch.Generator(torch.device("cpu")).manual_seed(int(seed))).to(device), lambda _, size, dtype, device, seed: device.type == 'privateuseone')
# https://github.com/microsoft/DirectML/issues/400
CondFunc('torch.Tensor.new', lambda orig, self, *args, **kwargs: orig(self.cpu(), *args, **kwargs).to(self.device), lambda orig, self, *args, **kwargs: torch.dml.is_directml_device(self.device))
def cuda(self: torch.Tensor):
return self.to(torch.dml.current_device())
torch.Tensor.cuda = cuda
# https://github.com/lshqqytiger/stable-diffusion-webui-directml/issues/436
_pow_ = torch.Tensor.pow_
def pow_(self: torch.Tensor, *args, **kwargs):
if self.dtype == torch.float64:
return _pow_(self.cpu(), *args, **kwargs).to(self.device)
return _pow_(self, *args, **kwargs)
torch.Tensor.pow_ = pow_
_load = torch.load
def load(f, map_location = "cpu", *args, **kwargs):
if type(map_location) in (str, torch.device,):
device = torch.device(map_location)
if device.type == "privateuseone":
data = _load(f, *args, map_location="cpu", **kwargs)
for k in data:
for weight in data[k]:
data[k][weight] = data[k][weight].to(device)
return data
return _load(f, *args, map_location=map_location, **kwargs)
torch.load = load
-43
View File
@@ -1,43 +0,0 @@
import torch
import transformers.models.clip.modeling_clip
# Copied from transformers.models.bart.modeling_bart._make_causal_mask
def _make_causal_mask(
input_ids_shape: torch.Size, dtype: torch.dtype, device: torch.device, past_key_values_length: int = 0
):
"""
Make causal mask used for bi-directional self-attention.
"""
bsz, tgt_len = input_ids_shape
min = torch.tensor(torch.finfo(dtype).min, device="cpu")
mask = torch.full((tgt_len, tgt_len), min, device=device) # https://discord.com/channels/1101998836328697867/1127441997184122920
mask_cond = torch.arange(mask.size(-1), device=device)
mask.masked_fill_(mask_cond < (mask_cond + 1).view(mask.size(-1), 1), 0)
mask = mask.to(dtype)
if past_key_values_length > 0:
mask = torch.cat([torch.zeros(tgt_len, past_key_values_length, dtype=dtype, device=device), mask], dim=-1)
return mask[None, None, :, :].expand(bsz, 1, tgt_len, tgt_len + past_key_values_length)
def CLIPTextEmbeddings_forward(
self: transformers.models.clip.modeling_clip.CLIPTextEmbeddings,
input_ids: torch.LongTensor | None = None,
position_ids: torch.LongTensor | None = None,
inputs_embeds: torch.FloatTensor | None = None,
) -> torch.Tensor:
from modules.devices import dtype
seq_length = input_ids.shape[-1] if input_ids is not None else inputs_embeds.shape[-2]
if position_ids is None:
position_ids = self.position_ids[:, :seq_length]
if inputs_embeds is None:
inputs_embeds = self.token_embedding(input_ids).type(dtype) # Type correction.
position_embeddings = self.position_embedding(position_ids)
embeddings = inputs_embeds + position_embeddings
return embeddings
transformers.models.clip.modeling_clip._make_causal_mask = _make_causal_mask
transformers.models.clip.modeling_clip.CLIPTextEmbeddings.forward = CLIPTextEmbeddings_forward
-19
View File
@@ -1,19 +0,0 @@
import torch
from collections.abc import Callable
from modules.shared import log, opts
def catch_nan(func: Callable[[], torch.Tensor]):
if not opts.directml_catch_nan:
return func()
tries = 0
tensor = func()
while tensor.isnan().sum() != 0 and tries < 10:
if tries == 0:
log.warning("NaN is produced. Retry with same values...")
tries += 1
tensor = func()
if tensor.isnan().sum() != 0:
log.error("Failed to cover NaN.")
return tensor
-31
View File
@@ -1,31 +0,0 @@
from os import getpid
from collections import defaultdict
from modules.dml.pdh import HQuery, HCounter, expand_wildcard_path
class MemoryProvider:
hQuery: HQuery
hCounters: defaultdict[str, list[HCounter]]
def __init__(self):
self.hQuery = HQuery()
self.hCounters = defaultdict(list)
def get_memory(self, device_id: int) -> dict[str, int]:
if len(self.hCounters) == 0:
pid = getpid()
paths_dedicated = expand_wildcard_path(f"\\GPU Process Memory(pid_{pid}_*_phys_{device_id})\\Dedicated Usage")
paths_committed = expand_wildcard_path(f"\\GPU Process Memory(pid_{pid}_*_phys_{device_id})\\Total Committed")
for path in paths_dedicated:
self.hCounters["dedicated_usage"].append(self.hQuery.add_counter(path))
for path in paths_committed:
self.hCounters["total_committed"].append(self.hQuery.add_counter(path))
self.hQuery.collect_data()
result = defaultdict(int)
for key in self.hCounters:
for hCounter in self.hCounters[key]:
result[key] += hCounter.get_formatted_value(int)
return dict(result)
def __del__(self):
self.hQuery.close()
-10
View File
@@ -1,10 +0,0 @@
from .driver.atiadlxx import ATIADLxx
class AMDMemoryProvider:
driver: ATIADLxx = ATIADLxx()
@staticmethod
def mem_get_info(index):
usage = AMDMemoryProvider.driver.get_dedicated_vram_usage(index) * (1 << 20)
return (AMDMemoryProvider.driver.iHyperMemorySize - usage, AMDMemoryProvider.driver.iHyperMemorySize)
-47
View File
@@ -1,47 +0,0 @@
import ctypes as C
from modules.dml.memory_amd.driver.atiadlxx_apis import ADL2_Main_Control_Create, ADL_Main_Memory_Alloc, ADL2_Adapter_NumberOfAdapters_Get, ADL2_Adapter_AdapterInfo_Get, ADL2_Adapter_MemoryInfo2_Get, ADL2_Adapter_DedicatedVRAMUsage_Get, ADL2_Adapter_VRAMUsage_Get
from modules.dml.memory_amd.driver.atiadlxx_structures import ADL_CONTEXT_HANDLE, AdapterInfo, LPAdapterInfo, ADLMemoryInfo2
from modules.dml.memory_amd.driver.atiadlxx_defines import ADL_OK
class ATIADLxx:
iHyperMemorySize = 0
def __init__(self):
self.context = ADL_CONTEXT_HANDLE()
ADL2_Main_Control_Create(ADL_Main_Memory_Alloc, 1, C.byref(self.context))
num_adapters = C.c_int(-1)
ADL2_Adapter_NumberOfAdapters_Get(self.context, C.byref(num_adapters))
AdapterInfoArray = (AdapterInfo * num_adapters.value)()
ADL2_Adapter_AdapterInfo_Get(self.context, C.cast(AdapterInfoArray, LPAdapterInfo), C.sizeof(AdapterInfoArray))
self.devices = []
busNumbers = []
for adapter in AdapterInfoArray:
if adapter.iBusNumber not in busNumbers: # filter duplicate device
self.devices.append(adapter)
busNumbers.append(adapter.iBusNumber)
self.iHyperMemorySize = self.get_memory_info2(0).iHyperMemorySize
def get_memory_info2(self, adapterIndex: int) -> ADLMemoryInfo2:
info = ADLMemoryInfo2()
if ADL2_Adapter_MemoryInfo2_Get(self.context, adapterIndex, C.byref(info)) != ADL_OK:
raise RuntimeError("ADL2: Failed to get MemoryInfo2")
return info
def get_dedicated_vram_usage(self, index: int) -> int:
usage = C.c_int(-1)
if ADL2_Adapter_DedicatedVRAMUsage_Get(self.context, self.devices[index].iAdapterIndex, C.byref(usage)) != ADL_OK:
raise RuntimeError("ADL2: Failed to get DedicatedVRAMUsage")
return usage.value
def get_vram_usage(self, index: int) -> int:
usage = C.c_int(-1)
if ADL2_Adapter_VRAMUsage_Get(self.context, self.devices[index].iAdapterIndex, C.byref(usage)) != ADL_OK:
raise RuntimeError("ADL2: Failed to get VRAMUsage")
return usage.value
@@ -1,50 +0,0 @@
import ctypes as C
from platform import platform
from modules.dml.memory_amd.driver.atiadlxx_structures import ADL_CONTEXT_HANDLE, LPAdapterInfo, ADLMemoryInfo2
if 'Windows' in platform():
atiadlxx = C.WinDLL("atiadlxx.dll")
else:
atiadlxx = C.CDLL("libatiadlxx.so") # Not tested on Linux system. But will be supported.
ADL_MAIN_MALLOC_CALLBACK = C.CFUNCTYPE(C.c_void_p, C.c_int)
ADL_MAIN_FREE_CALLBACK = C.CFUNCTYPE(None, C.POINTER(C.c_void_p))
@ADL_MAIN_MALLOC_CALLBACK
def ADL_Main_Memory_Alloc(iSize):
return C._malloc(iSize)
@ADL_MAIN_FREE_CALLBACK
def ADL_Main_Memory_Free(lpBuffer):
if lpBuffer[0] is not None:
C._free(lpBuffer[0])
lpBuffer[0] = None
ADL2_Main_Control_Create = atiadlxx.ADL2_Main_Control_Create
ADL2_Main_Control_Create.restype = C.c_int
ADL2_Main_Control_Create.argtypes = [ADL_MAIN_MALLOC_CALLBACK, C.c_int, ADL_CONTEXT_HANDLE]
ADL2_Adapter_NumberOfAdapters_Get = atiadlxx.ADL2_Adapter_NumberOfAdapters_Get
ADL2_Adapter_NumberOfAdapters_Get.restype = C.c_int
ADL2_Adapter_NumberOfAdapters_Get.argtypes = [ADL_CONTEXT_HANDLE, C.POINTER(C.c_int)]
ADL2_Adapter_AdapterInfo_Get = atiadlxx.ADL2_Adapter_AdapterInfo_Get
ADL2_Adapter_AdapterInfo_Get.restype = C.c_int
ADL2_Adapter_AdapterInfo_Get.argtypes = [ADL_CONTEXT_HANDLE, LPAdapterInfo, C.c_int]
ADL2_Adapter_MemoryInfo2_Get = atiadlxx.ADL2_Adapter_MemoryInfo2_Get
ADL2_Adapter_MemoryInfo2_Get.restype = C.c_int
ADL2_Adapter_MemoryInfo2_Get.argtypes = [ADL_CONTEXT_HANDLE, C.c_int, C.POINTER(ADLMemoryInfo2)]
ADL2_Adapter_DedicatedVRAMUsage_Get = atiadlxx.ADL2_Adapter_DedicatedVRAMUsage_Get
ADL2_Adapter_DedicatedVRAMUsage_Get.restype = C.c_int
ADL2_Adapter_DedicatedVRAMUsage_Get.argtypes = [ADL_CONTEXT_HANDLE, C.c_int, C.POINTER(C.c_int)]
ADL2_Adapter_VRAMUsage_Get = atiadlxx.ADL2_Adapter_VRAMUsage_Get
ADL2_Adapter_VRAMUsage_Get.restype = C.c_int
ADL2_Adapter_VRAMUsage_Get.argtypes = [ADL_CONTEXT_HANDLE, C.c_int, C.POINTER(C.c_int)]
@@ -1 +0,0 @@
ADL_OK = 0
@@ -1,90 +0,0 @@
import ctypes as C
class _ADLPMActivity(C.Structure):
__slot__ = [
'iActivityPercent',
'iCurrentBusLanes',
'iCurrentBusSpeed',
'iCurrentPerformanceLevel',
'iEngineClock',
'iMaximumBusLanes',
'iMemoryClock',
'iReserved',
'iSize',
'iVddc',
]
_ADLPMActivity._fields_ = [ # pylint: disable=protected-access
('iActivityPercent', C.c_int),
('iCurrentBusLanes', C.c_int),
('iCurrentBusSpeed', C.c_int),
('iCurrentPerformanceLevel', C.c_int),
('iEngineClock', C.c_int),
('iMaximumBusLanes', C.c_int),
('iMemoryClock', C.c_int),
('iReserved', C.c_int),
('iSize', C.c_int),
('iVddc', C.c_int),
]
ADLPMActivity = _ADLPMActivity
class _ADLMemoryInfo2(C.Structure):
__slot__ = [
'iHyperMemorySize',
'iInvisibleMemorySize',
'iMemoryBandwidth',
'iMemorySize',
'iVisibleMemorySize',
'strMemoryType'
]
_ADLMemoryInfo2._fields_ = [ # pylint: disable=protected-access
('iHyperMemorySize', C.c_longlong),
('iInvisibleMemorySize', C.c_longlong),
('iMemoryBandwidth', C.c_longlong),
('iMemorySize', C.c_longlong),
('iVisibleMemorySize', C.c_longlong),
('strMemoryType', C.c_char * 256)
]
ADLMemoryInfo2 = _ADLMemoryInfo2
class _AdapterInfo(C.Structure):
__slot__ = [
'iSize',
'iAdapterIndex',
'strUDID',
'iBusNumber',
'iDeviceNumber',
'iFunctionNumber',
'iVendorID',
'strAdapterName',
'strDisplayName',
'iPresent',
'iExist',
'strDriverPath',
'strDriverPathExt',
'strPNPString',
'iOSDisplayIndex',
]
_AdapterInfo._fields_ = [ # pylint: disable=protected-access
('iSize', C.c_int),
('iAdapterIndex', C.c_int),
('strUDID', C.c_char * 256),
('iBusNumber', C.c_int),
('iDeviceNumber', C.c_int),
('iFunctionNumber', C.c_int),
('iVendorID', C.c_int),
('strAdapterName', C.c_char * 256),
('strDisplayName', C.c_char * 256),
('iPresent', C.c_int),
('iExist', C.c_int),
('strDriverPath', C.c_char * 256),
('strDriverPathExt', C.c_char * 256),
('strPNPString', C.c_char * 256),
('iOSDisplayIndex', C.c_int)
]
AdapterInfo = _AdapterInfo
LPAdapterInfo = C.POINTER(_AdapterInfo)
ADL_CONTEXT_HANDLE = C.c_void_p
-90
View File
@@ -1,90 +0,0 @@
from ctypes import byref, cast, c_size_t
from ctypes.wintypes import LPCWSTR, DWORD, WCHAR
from typing import NamedTuple, TypeVar
from .apis import PdhExpandWildCardPathW, PdhOpenQueryW, PdhAddEnglishCounterW, PdhCollectQueryData, PdhGetFormattedCounterValue, PdhGetFormattedCounterArrayW, PdhCloseQuery
from .structures import PDH_HQUERY, PDH_HCOUNTER, PDH_FMT_COUNTERVALUE, PPDH_FMT_COUNTERVALUE_ITEM_W
from .defines import PDH_FMT_LARGE, PDH_FMT_DOUBLE, PDH_FMT_NOSCALE, PDH_NOEXPANDCOUNTERS, PDH_MORE_DATA, PDH_OK
from .msvcrt import malloc
from .errors import PDHError
class __InternalAbstraction(NamedTuple):
flag: int
attr_name: str
_type_map = {
int: __InternalAbstraction(PDH_FMT_LARGE, "largeValue"),
float: __InternalAbstraction(PDH_FMT_DOUBLE, "doubleValue"),
}
def expand_wildcard_path(path: str) -> list[str]:
listLength = DWORD(0)
if PdhExpandWildCardPathW(None, LPCWSTR(path), None, byref(listLength), PDH_NOEXPANDCOUNTERS) != PDH_MORE_DATA:
raise PDHError("Something went wrong.")
expanded = (WCHAR * listLength.value)()
if PdhExpandWildCardPathW(None, LPCWSTR(path), expanded, byref(listLength), PDH_NOEXPANDCOUNTERS) != PDH_OK:
raise PDHError(f"Couldn't expand wildcard path '{path}'")
result = []
cur = ""
for c in expanded:
if c == '\0':
result.append(cur)
cur = ""
else:
cur += c
result.pop()
return result
T = TypeVar("T", *_type_map.keys())
class HCounter(PDH_HCOUNTER):
def get_formatted_value(self, typ: T) -> T:
if typ not in _type_map:
raise PDHError(f"Invalid value type: {typ}")
flag, attr_name = _type_map[typ]
value = PDH_FMT_COUNTERVALUE()
if PdhGetFormattedCounterValue(self, DWORD(flag | PDH_FMT_NOSCALE), None, byref(value)) != PDH_OK:
raise PDHError("Couldn't get formatted counter value.")
return getattr(value.u, attr_name)
def get_formatted_dict(self, typ: T) -> dict[str, T]:
if typ not in _type_map:
raise PDHError(f"Invalid value type: {typ}")
flag, attr_name = _type_map[typ]
bufferSize = DWORD(0)
itemCount = DWORD(0)
if PdhGetFormattedCounterArrayW(self, DWORD(flag | PDH_FMT_NOSCALE), byref(bufferSize), byref(itemCount), None) != PDH_MORE_DATA:
raise PDHError("Something went wrong.")
itemBuffer = cast(malloc(c_size_t(bufferSize.value)), PPDH_FMT_COUNTERVALUE_ITEM_W)
if PdhGetFormattedCounterArrayW(self, DWORD(flag | PDH_FMT_NOSCALE), byref(bufferSize), byref(itemCount), itemBuffer) != PDH_OK:
raise PDHError("Couldn't get formatted counter array.")
result: dict[str, T] = {}
for i in range(0, itemCount.value):
item = itemBuffer[i]
result[item.szName] = getattr(item.FmtValue.u, attr_name)
return result
class HQuery(PDH_HQUERY):
def __init__(self):
super().__init__()
if PdhOpenQueryW(None, None, byref(self)) != PDH_OK:
raise PDHError("Couldn't open PDH query.")
def add_counter(self, path: str) -> HCounter:
hCounter = HCounter()
if PdhAddEnglishCounterW(self, LPCWSTR(path), None, byref(hCounter)) != PDH_OK:
raise PDHError("Couldn't add counter query.")
return hCounter
def collect_data(self):
if PdhCollectQueryData(self) != PDH_OK:
raise PDHError("Couldn't collect query data.")
def close(self):
if PdhCloseQuery(self) != PDH_OK:
raise PDHError("Couldn't close PDH query.")
-37
View File
@@ -1,37 +0,0 @@
from ctypes import CDLL, POINTER
from ctypes.wintypes import LPCWSTR, LPDWORD, DWORD
from collections.abc import Callable
from .structures import PDH_HQUERY, PDH_HCOUNTER, PPDH_FMT_COUNTERVALUE, PPDH_FMT_COUNTERVALUE_ITEM_W
from .defines import PDH_FUNCTION, PZZWSTR, DWORD_PTR
pdh = CDLL("pdh.dll")
PdhExpandWildCardPathW: Callable = pdh.PdhExpandWildCardPathW
PdhExpandWildCardPathW.restype = PDH_FUNCTION
PdhExpandWildCardPathW.argtypes = [LPCWSTR, LPCWSTR, PZZWSTR, LPDWORD, DWORD]
PdhOpenQueryW: Callable = pdh.PdhOpenQueryW
PdhOpenQueryW.restype = PDH_FUNCTION
PdhOpenQueryW.argtypes = [LPCWSTR, DWORD_PTR, POINTER(PDH_HQUERY)]
PdhAddEnglishCounterW: Callable = pdh.PdhAddEnglishCounterW
PdhAddEnglishCounterW.restype = PDH_FUNCTION
PdhAddEnglishCounterW.argtypes = [PDH_HQUERY, LPCWSTR, DWORD_PTR, POINTER(PDH_HCOUNTER)]
PdhCollectQueryData: Callable = pdh.PdhCollectQueryData
PdhCollectQueryData.restype = PDH_FUNCTION
PdhCollectQueryData.argtypes = [PDH_HQUERY]
PdhGetFormattedCounterValue: Callable = pdh.PdhGetFormattedCounterValue
PdhGetFormattedCounterValue.restype = PDH_FUNCTION
PdhGetFormattedCounterValue.argtypes = [PDH_HCOUNTER, DWORD, LPDWORD, PPDH_FMT_COUNTERVALUE]
PdhGetFormattedCounterArrayW: Callable = pdh.PdhGetFormattedCounterArrayW
PdhGetFormattedCounterArrayW.restype = PDH_FUNCTION
PdhGetFormattedCounterArrayW.argtypes = [PDH_HCOUNTER, DWORD, LPDWORD, LPDWORD, PPDH_FMT_COUNTERVALUE_ITEM_W]
PdhCloseQuery: Callable = pdh.PdhCloseQuery
PdhCloseQuery.restype = PDH_FUNCTION
PdhCloseQuery.argtypes = [PDH_HQUERY]
-23
View File
@@ -1,23 +0,0 @@
from ctypes import c_int, POINTER
from ctypes.wintypes import DWORD, WCHAR
PDH_FUNCTION = c_int
PDH_OK = 0x00000000
PDH_MORE_DATA = -2147481646#0x800007D2
DWORD_PTR = POINTER(DWORD)
PWSTR = POINTER(WCHAR)
PZZWSTR = POINTER(WCHAR)
PDH_NOEXPANDCOUNTERS = 1
PDH_NOEXPANDINSTANCES = 2
PDH_REFRESHCOUNTERS = 4
PDH_FMT_LONG = 0x00000100
PDH_FMT_DOUBLE = 0x00000200
PDH_FMT_LARGE = 0x00000400
PDH_FMT_NOSCALE = 0x00001000
PDH_FMT_1000 = 0x00002000
PDH_FMT_NOCAP100 = 0x00008000
-3
View File
@@ -1,3 +0,0 @@
class PDHError(Exception):
def __init__(self, message: str):
super().__init__(message)
-13
View File
@@ -1,13 +0,0 @@
from ctypes import CDLL, c_void_p, c_size_t
msvcrt = CDLL("msvcrt")
malloc = msvcrt.malloc
malloc.restype = c_void_p
malloc.argtypes = [c_size_t]
free = msvcrt.free
free.restype = None
free.argtypes = [c_void_p]
-45
View File
@@ -1,45 +0,0 @@
from ctypes import Union, c_double, c_longlong, Structure, POINTER
from ctypes.wintypes import HANDLE, LONG, LPCSTR, LPCWSTR, DWORD, LPWSTR
PDH_HQUERY = HANDLE
PDH_HCOUNTER = HANDLE
class PDH_FMT_COUNTERVALUE_U(Union):
_fields_ = [
("longValue", LONG),
("doubleValue", c_double),
("largeValue", c_longlong),
("AnsiStringValue", LPCSTR),
("WideStringValue", LPCWSTR),
]
longValue: int
doubleValue: float
largeValue: int
AnsiStringValue: LPCSTR
WideStringValue: LPCWSTR
class PDH_FMT_COUNTERVALUE(Structure):
_anonymous_ = ("u",)
_fields_ = [
("CStatus", DWORD),
("u", PDH_FMT_COUNTERVALUE_U),
]
CStatus: DWORD
u: PDH_FMT_COUNTERVALUE_U
PPDH_FMT_COUNTERVALUE = POINTER(PDH_FMT_COUNTERVALUE)
class PDH_FMT_COUNTERVALUE_ITEM_W(Structure):
_fields_ = [
("szName", LPWSTR),
("FmtValue", PDH_FMT_COUNTERVALUE),
]
szName: str
FmtValue: PDH_FMT_COUNTERVALUE
PPDH_FMT_COUNTERVALUE_ITEM_W = POINTER(PDH_FMT_COUNTERVALUE_ITEM_W)
-9
View File
@@ -1,9 +0,0 @@
from typing import Union
import torch
rDevice = Union[torch.device, int]
def get_device(device: rDevice | None=None) -> torch.device:
if device is None:
device = torch.dml.current_device()
return torch.device(device)
-2
View File
@@ -47,8 +47,6 @@ else:
def get_default_execution_provider() -> ExecutionProvider:
if devices.backend == "cpu":
return ExecutionProvider.CPU
elif devices.backend == "directml":
return ExecutionProvider.DirectML
elif devices.backend == "cuda":
return ExecutionProvider.CUDA
elif devices.backend == "rocm":
+1 -3
View File
@@ -24,9 +24,7 @@ def create_ui():
with gr.TabItem("Provider", id="onnxep"):
gr.Markdown("Install ONNX execution provider")
ep_default = None
if cmd_opts.use_directml:
ep_default = ExecutionProvider.DirectML
elif cmd_opts.use_cuda:
if cmd_opts.use_cuda:
ep_default = ExecutionProvider.CUDA
elif cmd_opts.use_rocm:
ep_default = ExecutionProvider.ROCm
-4
View File
@@ -108,8 +108,6 @@ def dynamic_scaled_dot_product_attention(query: torch.FloatTensor, key: torch.Fl
attn_mask=attn_mask[start_idx:end_idx, :, :, :] if attn_mask is not None else attn_mask,
dropout_p=dropout_p, is_causal=is_causal, scale=scale, **kwargs
)
if devices.backend != "directml":
getattr(torch, query.device.type).synchronize()
else:
hidden_states = devices.sdpa_pre_dyanmic_atten(query, key, value, attn_mask=attn_mask, dropout_p=dropout_p, is_causal=is_causal, scale=scale, **kwargs)
if is_unsqueezed:
@@ -252,8 +250,6 @@ class DynamicAttnProcessorBMM:
hidden_states[start_idx:end_idx] = attn_slice
del attn_slice
if devices.backend != "directml":
getattr(torch, query.device.type).synchronize()
else:
attention_probs = attn.get_attention_scores(query, key, attention_mask)
hidden_states = torch.bmm(attention_probs, value)
+1 -7
View File
@@ -98,13 +98,7 @@ def get_fft_device():
def no_gpu_complex_support():
mps_available = hasattr(torch.backends, "mps") and torch.backends.mps.is_available()
try:
import torch_directml
except ImportError:
dml_available = False
else:
dml_available = torch_directml.is_available()
return mps_available or dml_available
return mps_available
def filter_skip(x, threshold, scale, scale_high):
+1 -1
View File
@@ -129,6 +129,6 @@ def install():
knobs.autotuning.listener = make_autotune_listener(getattr(knobs.autotuning, 'listener', None))
knobs.compilation.listener = make_compile_listener(getattr(knobs.compilation, 'listener', None))
Autotuner._bench = bench_hook(Autotuner._bench) # pylint: disable=protected-access
log.debug('Kernel autotune: reporting installed')
# log.debug('Kernel autotune: reporting installed')
except Exception as e:
log.warning(f'Kernel autotune: reporting install failed: {e}')
-4
View File
@@ -270,10 +270,6 @@ class OffloadHook(accelerate.hooks.ModelHook):
clean_result=False,
)
offload_dir = getattr(module, "offload_dir", os.path.join(shared.opts.accelerate_offload_path, module.__class__.__name__))
if devices.backend == "directml":
for k, v in device_map.items():
if isinstance(v, int):
device_map[k] = f"{devices.device.type}:{v}" # int implies CUDA or XPU device, but it will break DirectML backend so we add type
if debug:
log.trace(f'Offload: type=balanced op=dispatch map={device_map}')
if device_map is not None:
-10
View File
@@ -88,13 +88,6 @@ elif cmd_opts.use_ipex or devices.has_xpu():
log.error(f'IPEX initialization failed: {e}')
if os.environ.get('SD_DEVICE_DEBUG', None) is not None:
errors.display(e, 'IPEX')
elif cmd_opts.use_directml:
from modules.dml import directml_init
ok, e = directml_init()
if not ok:
log.error(f'DirectML initialization failed: {e}')
if os.environ.get('SD_DEVICE_DEBUG', None) is not None:
errors.display(e, 'DirectML')
elif cmd_opts.use_rocm or devices.has_rocm():
from modules.rocm import rocm_init
ok, e = rocm_init()
@@ -167,7 +160,6 @@ if cmd_opts.locale is not None:
opts.data['ui_locale'] = cmd_opts.locale
log.debug('Initializing: backend')
from modules.dml import directml_do_hijack
if cmd_opts.use_xformers:
opts.data['cross_attention_optimization'] = 'xFormers'
opts.data['uni_pc_lower_order_final'] = opts.schedulers_use_loworder # compatibility
@@ -191,8 +183,6 @@ device = devices.device
parallel_processing_allowed = not cmd_opts.lowvram
mem_mon = modules.memmon.MemUsageMonitor("MemMon", devices.device)
history = history.History()
if devices.backend == "directml":
directml_do_hijack()
log.debug('Quantization: registered=SDNQ')
try:
+1 -1
View File
@@ -56,7 +56,7 @@ def get_default_modes(cmd_opts, mem_stat):
agent = devices.get_hip_agent()
if agent.gfx_version < 0x1100:
default_sdp_override_options = ['Dynamic attention'] # only RDNA2 and older GPUs needs this
elif devices.backend in {"directml", "cpu", "mps"}:
elif devices.backend in {"cpu", "mps"}:
default_sdp_override_options = ['Dynamic attention']
if devices.get_optimal_device_name() != "cpu":
-13
View File
@@ -25,14 +25,6 @@ def list_onnx_providers():
return "CPU", []
def list_dml_providers():
try:
from modules.dml import memory_providers, default_memory_provider
return default_memory_provider, memory_providers
except Exception:
return "Performance Counter", []
def list_checkpoint_titles():
import modules.sd_models # pylint: disable=redefined-outer-name
return modules.sd_models.checkpoint_titles()
@@ -83,7 +75,6 @@ def create_settings(cmd_opts):
default_xetcache_dir = os.environ.get("HF_XET_CACHE ", None) or os.path.join(paths.models_path, 'xet')
default_onnx_execution_provider, default_onnx_execution_providers = list_onnx_providers()
default_dml_memory_provider, default_dml_memory_providers = list_dml_providers()
hide_dirs = {"visible": not cmd_opts.hide_ui_dir_config}
@@ -313,10 +304,6 @@ def create_settings(cmd_opts):
"openvino_compile_backend": OptionInfo("openvino_fx", "OpenVINO compile backend", gr.Radio, {"choices": ["openvino", "openvino_fx"], "visible": cmd_opts.use_openvino}),
"openvino_disable_model_caching": OptionInfo(True, "OpenVINO disable model caching", gr.Checkbox, {"visible": cmd_opts.use_openvino}),
"openvino_disable_memory_cleanup": OptionInfo(True, "OpenVINO disable memory cleanup", gr.Checkbox, {"visible": cmd_opts.use_openvino}),
"directml_sep": OptionInfo("<h2>DirectML</h2>", "", gr.HTML, {"visible": devices.backend == "directml"}),
"directml_memory_provider": OptionInfo(default_dml_memory_provider, "DirectML memory stats provider", gr.Radio, {"choices": default_dml_memory_providers, "visible": devices.backend == "directml"}),
"directml_catch_nan": OptionInfo(False, "DirectML retry ops for NaN", gr.Checkbox, {"visible": devices.backend == "directml"}),
}))
# --- Pipeline Modifiers ---
-6
View File
@@ -135,9 +135,6 @@ def run_settings(*args):
from modules.onnx_impl import install_olive, initialize_onnx_pipelines
install_olive()
initialize_onnx_pipelines()
if shared.cmd_opts.use_directml:
from modules.dml import directml_override_opts
directml_override_opts()
if shared.cmd_opts.use_openvino:
if "Model" not in shared.opts.cuda_compile:
log.warning("OpenVINO: Overriding Torch Compile Model")
@@ -196,9 +193,6 @@ def run_settings_single(value, key, progress=False, force=False):
if key == "cuda_compile_backend" and value == "olive-ai":
from modules.onnx_impl import install_olive
install_olive()
if shared.cmd_opts.use_directml:
from modules.dml import directml_override_opts
directml_override_opts()
shared.opts.save(silent=True)
if key == 'sd_text_encoder':
sd_models.reload_text_encoder() # apply the change now; reloads the model for encoders with no in-place swap
-1
View File
@@ -109,7 +109,6 @@ main.ignore-paths=[
"modules/schedulers/scheduler_*.py",
"modules/apg",
"modules/cfgzero",
"modules/dml",
"modules/face",
"modules/flash_attn_triton_amd",
"modules/ggml",
+1 -1
Submodule wiki updated: ee4e24dbb8...9ff9ec3bb0