diff --git a/README.md b/README.md index abdcb1e..3074988 100644 --- a/README.md +++ b/README.md @@ -147,6 +147,7 @@ This repository offers various extension nodes for ComfyUI. Nodes here have diff * When `key_opt` is empty, the `ckpt_name` is set as the cache key. The cache key output can be used for deletion purposes with Remove Back End. * This node resolves the issue of reloading checkpoints during workflow switching. * `Stable Cascade Checkpoint Loader (Inspire)`: This node provides a feature that allows you to load the `stage_b` and `stage_c` checkpoints of Stable Cascade at once, and it also provides a backend caching feature, optionally. + * `Is Cached (Inspire)`: Returns whether the cache exists. ### Conditioning - Nodes for conditionings * `Concat Conditionings with Multiplier (Inspire)`: Concatenating an arbitrary number of Conditionings while applying a multiplier for each Conditioning. The multiplier depends on `comfy_PoP`, so [comfy_PoP](https://github.com/picturesonpictures/comfy_PoP) must be installed. diff --git a/__init__.py b/__init__.py index 023a96e..3e989e7 100644 --- a/__init__.py +++ b/__init__.py @@ -7,7 +7,7 @@ import importlib -version_code = [1, 8] +version_code = [1, 9] version_str = f"V{version_code[0]}.{version_code[1]}" + (f'.{version_code[2]}' if len(version_code) > 2 else '') print(f"### Loading: ComfyUI-Inspire-Pack ({version_str})") diff --git a/inspire/backend_support.py b/inspire/backend_support.py index edebb2f..9b4eb28 100644 --- a/inspire/backend_support.py +++ b/inspire/backend_support.py @@ -1,5 +1,6 @@ import json import os +from .libs import common import folder_paths import nodes @@ -478,6 +479,74 @@ def doit(self, stage_b, key_opt_b, stage_c, key_opt_c, cache_mode): return b_model, b_vae, c_model, c_vae, clip_vision, clip, key_b, key_c +class IsCached: + @classmethod + def INPUT_TYPES(s): + return { + "required": { + "key": ("STRING", {"multiline": False}), + }, + "hidden": { + "unique_id": "UNIQUE_ID" + } + } + + RETURN_TYPES = ("BOOLEAN", ) + FUNCTION = "doit" + + CATEGORY = "InspirePack/Backend" + + @staticmethod + def IS_CHANGED(key, unique_id): + return common.is_changed(unique_id, key in cache) + + def doit(self, key, unique_id): + return (key in cache,) + + +# WIP: not properly working, yet +class CacheBridge: + @classmethod + def INPUT_TYPES(s): + return { + "required": { + "value": (any_typ,), + "mode": ("BOOLEAN", {"default": True, "label_off": "cached", "label_on": "passthrough"}), + }, + "hidden": { + "unique_id": "UNIQUE_ID" + } + } + + RETURN_TYPES = (any_typ, ) + RETURN_NAMES = ("value",) + + FUNCTION = "doit" + + CATEGORY = "InspirePack/Backend" + + @staticmethod + def IS_CHANGED(value, mode, unique_id): + if not mode and unique_id in common.changed_cache: + return common.not_changed_value(unique_id) + else: + return common.changed_value(unique_id) + + def doit(self, value, mode, unique_id): + if not mode: + # cache mode + if unique_id not in common.changed_cache: + common.changed_cache[unique_id] = value + common.changed_count_cache[unique_id] = 0 + + return (common.changed_cache[unique_id],) + else: + common.changed_cache[unique_id] = value + common.changed_count_cache[unique_id] = 0 + + return (common.changed_cache[unique_id],) + + NODE_CLASS_MAPPINGS = { "CacheBackendData //Inspire": CacheBackendData, "CacheBackendDataNumberKey //Inspire": CacheBackendDataNumberKey, @@ -489,7 +558,9 @@ def doit(self, stage_b, key_opt_b, stage_c, key_opt_c, cache_mode): "RemoveBackendDataNumberKey //Inspire": RemoveBackendDataNumberKey, "ShowCachedInfo //Inspire": ShowCachedInfo, "CheckpointLoaderSimpleShared //Inspire": CheckpointLoaderSimpleShared, - "StableCascade_CheckpointLoader //Inspire": StableCascade_CheckpointLoader + "StableCascade_CheckpointLoader //Inspire": StableCascade_CheckpointLoader, + "IsCached //Inspire": IsCached, + # "CacheBridge //Inspire": CacheBridge, } NODE_DISPLAY_NAME_MAPPINGS = { @@ -503,5 +574,7 @@ def doit(self, stage_b, key_opt_b, stage_c, key_opt_c, cache_mode): "RemoveBackendDataNumberKey //Inspire": "Remove Backend Data [NumberKey] (Inspire)", "ShowCachedInfo //Inspire": "Show Cached Info (Inspire)", "CheckpointLoaderSimpleShared //Inspire": "Shared Checkpoint Loader (Inspire)", - "StableCascade_CheckpointLoader //Inspire": "Stable Cascade Checkpoint Loader (Inspire)" + "StableCascade_CheckpointLoader //Inspire": "Stable Cascade Checkpoint Loader (Inspire)", + "IsCached //Inspire": "Is Cached (Inspire)", + # "CacheBridge //Inspire": "Cache Bridge (Inspire)" } diff --git a/inspire/inspire_server.py b/inspire/inspire_server.py index 241b8f4..01b8a88 100644 --- a/inspire/inspire_server.py +++ b/inspire/inspire_server.py @@ -6,6 +6,7 @@ from . import prompt_support from aiohttp import web from . import backend_support +from .libs import common max_seed = 2**32 - 1 @@ -354,6 +355,21 @@ def force_reset_useless_params(json_data): return json_data +def clear_unused_node_changed_cache(json_data): + prompt = json_data['prompt'] + + unused = [] + for x in common.changed_cache.keys(): + if x not in prompt: + unused.append(x) + + for x in unused: + del common.changed_cache[x] + del common.changed_count_cache[x] + + return json_data + + def onprompt(json_data): prompt_support.list_counter_map = {} @@ -367,6 +383,7 @@ def onprompt(json_data): populate_wildcards(json_data) force_reset_useless_params(json_data) + clear_unused_node_changed_cache(json_data) return json_data diff --git a/inspire/libs/common.py b/inspire/libs/common.py index 7a4b296..84cba0e 100644 --- a/inspire/libs/common.py +++ b/inspire/libs/common.py @@ -12,3 +12,30 @@ def impact_sampling(*args, **kwargs): raise Exception(f"[ERROR] You need to install 'ComfyUI-Impact-Pack'") return nodes.NODE_CLASS_MAPPINGS['RegionalSampler'].separated_sample(*args, **kwargs) + + +changed_count_cache = {} +changed_cache = {} + + +def changed_value(uid): + v = changed_count_cache.get(uid, 0) + changed_count_cache[uid] = v + 1 + return v + 1 + + +def not_changed_value(uid): + return changed_count_cache.get(uid, 0) + + +def is_changed(uid, value): + if uid not in changed_cache or changed_cache[uid] != value: + res = changed_value(uid) + else: + res = not_changed_value(uid) + + changed_cache[uid] = value + + print(f"keys: {changed_cache.keys()}") + + return res diff --git a/pyproject.toml b/pyproject.toml index 020a40f..37b3042 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,7 +1,7 @@ [project] name = "comfyui-inspire-pack" description = "This extension provides various nodes to support Lora Block Weight, Regional Nodes, Backend Cache, Prompt Utils, List Utils, Noise(Seed) Utils, ... and the Impact Pack." -version = "1.8" +version = "1.9" license = { file = "LICENSE" } dependencies = ["matplotlib", "cachetools"]