Unverified Commit 501d4e9c authored by unknown's avatar unknown
Browse files

Merge branch 'master' of github.com:AUTOMATIC1111/stable-diffusion-webui into gamepad

parents 5e1f4f74 ea9bd9fc
Loading
Loading
Loading
Loading
+2 −2
Original line number Original line Diff line number Diff line
@@ -66,8 +66,8 @@ titles = {


    "Interrogate": "Reconstruct prompt from existing image and put it into the prompt field.",
    "Interrogate": "Reconstruct prompt from existing image and put it into the prompt field.",


    "Images filename pattern": "Use following tags to define how filenames for images are chosen: [steps], [cfg], [prompt], [prompt_no_styles], [prompt_spaces], [width], [height], [styles], [sampler], [seed], [model_hash], [model_name], [prompt_words], [date], [datetime], [datetime<Format>], [datetime<Format><Time Zone>], [job_timestamp]; leave empty for default.",
    "Images filename pattern": "Use following tags to define how filenames for images are chosen: [steps], [cfg], [prompt_hash], [prompt], [prompt_no_styles], [prompt_spaces], [width], [height], [styles], [sampler], [seed], [model_hash], [model_name], [prompt_words], [date], [datetime], [datetime<Format>], [datetime<Format><Time Zone>], [job_timestamp]; leave empty for default.",
    "Directory name pattern": "Use following tags to define how subdirectories for images and grids are chosen: [steps], [cfg], [prompt], [prompt_no_styles], [prompt_spaces], [width], [height], [styles], [sampler], [seed], [model_hash], [model_name], [prompt_words], [date], [datetime], [datetime<Format>], [datetime<Format><Time Zone>], [job_timestamp]; leave empty for default.",
    "Directory name pattern": "Use following tags to define how subdirectories for images and grids are chosen: [steps], [cfg],[prompt_hash], [prompt], [prompt_no_styles], [prompt_spaces], [width], [height], [styles], [sampler], [seed], [model_hash], [model_name], [prompt_words], [date], [datetime], [datetime<Format>], [datetime<Format><Time Zone>], [job_timestamp]; leave empty for default.",
    "Max prompt words": "Set the maximum number of words to be used in the [prompt_words] option; ATTENTION: If the words are too long, they may exceed the maximum length of the file path that the system can handle",
    "Max prompt words": "Set the maximum number of words to be used in the [prompt_words] option; ATTENTION: If the words are too long, they may exceed the maximum length of the file path that the system can handle",


    "Loopback": "Process an image, use it as an input, repeat.",
    "Loopback": "Process an image, use it as an input, repeat.",
+7 −45
Original line number Original line Diff line number Diff line
import sys, os, shlex
import sys
import contextlib
import contextlib
import torch
import torch
from modules import errors
from modules import errors
from modules.sd_hijack_utils import CondFunc

from packaging import version
if sys.platform == "darwin":
    from modules import mac_specific




# has_mps is only available in nightly pytorch (for now) and macOS 12.3+.
# check `getattr` and try it for compatibility
def has_mps() -> bool:
def has_mps() -> bool:
    if not getattr(torch, 'has_mps', False):
    if sys.platform != "darwin":
        return False
    try:
        torch.zeros(1).to(torch.device("mps"))
        return True
    except Exception:
        return False
        return False

    else:
        return mac_specific.has_mps


def extract_device_id(args, name):
def extract_device_id(args, name):
    for x in range(len(args)):
    for x in range(len(args)):
@@ -155,36 +150,3 @@ def test_for_nans(x, where):
    message += " Use --disable-nan-check commandline argument to disable this check."
    message += " Use --disable-nan-check commandline argument to disable this check."


    raise NansException(message)
    raise NansException(message)


# MPS workaround for https://github.com/pytorch/pytorch/issues/89784
def cumsum_fix(input, cumsum_func, *args, **kwargs):
    if input.device.type == 'mps':
        output_dtype = kwargs.get('dtype', input.dtype)
        if output_dtype == torch.int64:
            return cumsum_func(input.cpu(), *args, **kwargs).to(input.device)
        elif cumsum_needs_bool_fix and output_dtype == torch.bool or cumsum_needs_int_fix and (output_dtype == torch.int8 or output_dtype == torch.int16):
            return cumsum_func(input.to(torch.int32), *args, **kwargs).to(torch.int64)
    return cumsum_func(input, *args, **kwargs)


if has_mps():
    if version.parse(torch.__version__) < version.parse("1.13"):
        # PyTorch 1.13 doesn't need these fixes but unfortunately is slower and has regressions that prevent training from working

        # MPS workaround for https://github.com/pytorch/pytorch/issues/79383
        CondFunc('torch.Tensor.to', lambda orig_func, self, *args, **kwargs: orig_func(self.contiguous(), *args, **kwargs),
                                                          lambda _, self, *args, **kwargs: self.device.type != 'mps' and (args and isinstance(args[0], torch.device) and args[0].type == 'mps' or isinstance(kwargs.get('device'), torch.device) and kwargs['device'].type == 'mps'))
        # MPS workaround for https://github.com/pytorch/pytorch/issues/80800 
        CondFunc('torch.nn.functional.layer_norm', lambda orig_func, *args, **kwargs: orig_func(*([args[0].contiguous()] + list(args[1:])), **kwargs),
                                                                                        lambda _, *args, **kwargs: args and isinstance(args[0], torch.Tensor) and args[0].device.type == 'mps')
        # MPS workaround for https://github.com/pytorch/pytorch/issues/90532
        CondFunc('torch.Tensor.numpy', lambda orig_func, self, *args, **kwargs: orig_func(self.detach(), *args, **kwargs), lambda _, self, *args, **kwargs: self.requires_grad)
    elif version.parse(torch.__version__) > version.parse("1.13.1"):
        cumsum_needs_int_fix = not torch.Tensor([1,2]).to(torch.device("mps")).equal(torch.ShortTensor([1,1]).to(torch.device("mps")).cumsum(0))
        cumsum_needs_bool_fix = not torch.BoolTensor([True,True]).to(device=torch.device("mps"), dtype=torch.int64).equal(torch.BoolTensor([True,False]).to(torch.device("mps")).cumsum(0))
        cumsum_fix_func = lambda orig_func, input, *args, **kwargs: cumsum_fix(input, orig_func, *args, **kwargs)
        CondFunc('torch.cumsum', cumsum_fix_func, None)
        CondFunc('torch.Tensor.cumsum', cumsum_fix_func, None)
        CondFunc('torch.narrow', lambda orig_func, *args, **kwargs: orig_func(*args, **kwargs).clone(), None)
+4 −0
Original line number Original line Diff line number Diff line
@@ -4,6 +4,7 @@ import os.path


import filelock
import filelock


from modules import shared
from modules.paths import data_path
from modules.paths import data_path




@@ -68,6 +69,9 @@ def sha256(filename, title):
    if sha256_value is not None:
    if sha256_value is not None:
        return sha256_value
        return sha256_value


    if shared.cmd_opts.no_hashing:
        return None

    print(f"Calculating sha256 for {filename}: ", end='')
    print(f"Calculating sha256 for {filename}: ", end='')
    sha256_value = calculate_sha256(filename)
    sha256_value = calculate_sha256(filename)
    print(f"{sha256_value}")
    print(f"{sha256_value}")
+1 −1
Original line number Original line Diff line number Diff line
@@ -307,7 +307,7 @@ class Hypernetwork:
    def shorthash(self):
    def shorthash(self):
        sha256 = hashes.sha256(self.filename, f'hypernet/{self.name}')
        sha256 = hashes.sha256(self.filename, f'hypernet/{self.name}')


        return sha256[0:10]
        return sha256[0:10] if sha256 else None




def list_hypernetworks(path):
def list_hypernetworks(path):
+14 −9
Original line number Original line Diff line number Diff line
@@ -16,6 +16,7 @@ from PIL import Image, ImageFont, ImageDraw, PngImagePlugin
from fonts.ttf import Roboto
from fonts.ttf import Roboto
import string
import string
import json
import json
import hashlib


from modules import sd_samplers, shared, script_callbacks
from modules import sd_samplers, shared, script_callbacks
from modules.shared import opts, cmd_opts
from modules.shared import opts, cmd_opts
@@ -130,7 +131,7 @@ class GridAnnotation:
        self.size = None
        self.size = None




def draw_grid_annotations(im, width, height, hor_texts, ver_texts):
def draw_grid_annotations(im, width, height, hor_texts, ver_texts, margin=0):
    def wrap(drawing, text, font, line_length):
    def wrap(drawing, text, font, line_length):
        lines = ['']
        lines = ['']
        for word in text.split():
        for word in text.split():
@@ -194,32 +195,35 @@ def draw_grid_annotations(im, width, height, hor_texts, ver_texts):
            line.allowed_width = allowed_width
            line.allowed_width = allowed_width


    hor_text_heights = [sum([line.size[1] + line_spacing for line in lines]) - line_spacing for lines in hor_texts]
    hor_text_heights = [sum([line.size[1] + line_spacing for line in lines]) - line_spacing for lines in hor_texts]
    ver_text_heights = [sum([line.size[1] + line_spacing for line in lines]) - line_spacing * len(lines) for lines in
    ver_text_heights = [sum([line.size[1] + line_spacing for line in lines]) - line_spacing * len(lines) for lines in ver_texts]
                        ver_texts]


    pad_top = 0 if sum(hor_text_heights) == 0 else max(hor_text_heights) + line_spacing * 2
    pad_top = 0 if sum(hor_text_heights) == 0 else max(hor_text_heights) + line_spacing * 2


    result = Image.new("RGB", (im.width + pad_left, im.height + pad_top), "white")
    result = Image.new("RGB", (im.width + pad_left + margin * (cols-1), im.height + pad_top + margin * (rows-1)), "white")
    result.paste(im, (pad_left, pad_top))

    for row in range(rows):
        for col in range(cols):
            cell = im.crop((width * col, height * row, width * (col+1), height * (row+1)))
            result.paste(cell, (pad_left + (width + margin) * col, pad_top + (height + margin) * row))


    d = ImageDraw.Draw(result)
    d = ImageDraw.Draw(result)


    for col in range(cols):
    for col in range(cols):
        x = pad_left + width * col + width / 2
        x = pad_left + (width + margin) * col + width / 2
        y = pad_top / 2 - hor_text_heights[col] / 2
        y = pad_top / 2 - hor_text_heights[col] / 2


        draw_texts(d, x, y, hor_texts[col], fnt, fontsize)
        draw_texts(d, x, y, hor_texts[col], fnt, fontsize)


    for row in range(rows):
    for row in range(rows):
        x = pad_left / 2
        x = pad_left / 2
        y = pad_top + height * row + height / 2 - ver_text_heights[row] / 2
        y = pad_top + (height + margin) * row + height / 2 - ver_text_heights[row] / 2


        draw_texts(d, x, y, ver_texts[row], fnt, fontsize)
        draw_texts(d, x, y, ver_texts[row], fnt, fontsize)


    return result
    return result




def draw_prompt_matrix(im, width, height, all_prompts):
def draw_prompt_matrix(im, width, height, all_prompts, margin=0):
    prompts = all_prompts[1:]
    prompts = all_prompts[1:]
    boundary = math.ceil(len(prompts) / 2)
    boundary = math.ceil(len(prompts) / 2)


@@ -229,7 +233,7 @@ def draw_prompt_matrix(im, width, height, all_prompts):
    hor_texts = [[GridAnnotation(x, is_active=pos & (1 << i) != 0) for i, x in enumerate(prompts_horiz)] for pos in range(1 << len(prompts_horiz))]
    hor_texts = [[GridAnnotation(x, is_active=pos & (1 << i) != 0) for i, x in enumerate(prompts_horiz)] for pos in range(1 << len(prompts_horiz))]
    ver_texts = [[GridAnnotation(x, is_active=pos & (1 << i) != 0) for i, x in enumerate(prompts_vert)] for pos in range(1 << len(prompts_vert))]
    ver_texts = [[GridAnnotation(x, is_active=pos & (1 << i) != 0) for i, x in enumerate(prompts_vert)] for pos in range(1 << len(prompts_vert))]


    return draw_grid_annotations(im, width, height, hor_texts, ver_texts)
    return draw_grid_annotations(im, width, height, hor_texts, ver_texts, margin)




def resize_image(resize_mode, im, width, height, upscaler_name=None):
def resize_image(resize_mode, im, width, height, upscaler_name=None):
@@ -340,6 +344,7 @@ class FilenameGenerator:
        'date': lambda self: datetime.datetime.now().strftime('%Y-%m-%d'),
        'date': lambda self: datetime.datetime.now().strftime('%Y-%m-%d'),
        'datetime': lambda self, *args: self.datetime(*args),  # accepts formats: [datetime], [datetime<Format>], [datetime<Format><Time Zone>]
        'datetime': lambda self, *args: self.datetime(*args),  # accepts formats: [datetime], [datetime<Format>], [datetime<Format><Time Zone>]
        'job_timestamp': lambda self: getattr(self.p, "job_timestamp", shared.state.job_timestamp),
        'job_timestamp': lambda self: getattr(self.p, "job_timestamp", shared.state.job_timestamp),
        'prompt_hash': lambda self: hashlib.sha256(self.prompt.encode()).hexdigest()[0:8],
        'prompt': lambda self: sanitize_filename_part(self.prompt),
        'prompt': lambda self: sanitize_filename_part(self.prompt),
        'prompt_no_styles': lambda self: self.prompt_no_style(),
        'prompt_no_styles': lambda self: self.prompt_no_style(),
        'prompt_spaces': lambda self: sanitize_filename_part(self.prompt, replace_spaces=False),
        'prompt_spaces': lambda self: sanitize_filename_part(self.prompt, replace_spaces=False),
Loading