mirror of
https://git.datalinker.icu/comfyanonymous/ComfyUI
synced 2026-09-06 12:47:05 +08:00
Fix IS_CHANGED for marking node as not changed
This commit is contained in:
parent
47d55b8b45
commit
2e5316232e
@ -93,11 +93,18 @@ class CacheKeySetInputSignature(CacheKeySet):
|
||||
self.subcache_keys[node_id] = (node_id, node["class_type"])
|
||||
|
||||
def get_node_signature(self, dynprompt, node_id):
|
||||
node = dynprompt.get_node(node_id)
|
||||
class_type = node["class_type"]
|
||||
class_def = nodes.NODE_CLASS_MAPPINGS[class_type]
|
||||
|
||||
signature = []
|
||||
ancestors, order_mapping = self.get_ordered_ancestry(dynprompt, node_id)
|
||||
signature.append(self.get_immediate_node_signature(dynprompt, node_id, order_mapping))
|
||||
for ancestor_id in ancestors:
|
||||
signature.append(self.get_immediate_node_signature(dynprompt, ancestor_id, order_mapping))
|
||||
if hasattr(class_def, "IS_CHANGED"):
|
||||
signature.append(self.get_immediate_node_signature(dynprompt, node_id, {}))
|
||||
else:
|
||||
ancestors, order_mapping = self.get_ordered_ancestry(dynprompt, node_id)
|
||||
signature.append(self.get_immediate_node_signature(dynprompt, node_id, order_mapping))
|
||||
for ancestor_id in ancestors:
|
||||
signature.append(self.get_immediate_node_signature(dynprompt, ancestor_id, order_mapping))
|
||||
return to_hashable(signature)
|
||||
|
||||
def get_immediate_node_signature(self, dynprompt, node_id, ancestor_order_mapping):
|
||||
@ -108,8 +115,13 @@ class CacheKeySetInputSignature(CacheKeySet):
|
||||
class_type = node["class_type"]
|
||||
class_def = nodes.NODE_CLASS_MAPPINGS[class_type]
|
||||
signature = [class_type, self.is_changed_cache.get(node_id)]
|
||||
|
||||
if self.include_node_id_in_input() or (hasattr(class_def, "NOT_IDEMPOTENT") and class_def.NOT_IDEMPOTENT) or include_unique_id_in_input(class_type):
|
||||
signature.append(node_id)
|
||||
|
||||
if hasattr(class_def, "IS_CHANGED"):
|
||||
return signature
|
||||
|
||||
inputs = node["inputs"]
|
||||
for key in sorted(inputs.keys()):
|
||||
if is_link(inputs[key]):
|
||||
|
||||
@ -497,6 +497,36 @@ class TestExecution:
|
||||
assert numpy.array(images[0]).min() == 63 and numpy.array(images[0]).max() == 63, "Image should have value 0.25"
|
||||
assert not result.did_run(test_node), "The execution should have been cached"
|
||||
|
||||
# This tests that a node does not re-execute when IS_CHANGED returs the same value (even if
|
||||
# inputs change)
|
||||
def test_is_changed_overrides_default_checks(self, client: ComfyClient, builder: GraphBuilder):
|
||||
g = builder
|
||||
changing_input = g.node("StubImage", content="BLACK", height=512, width=512, batch_size=1)
|
||||
test_node = g.node("TestCustomIsChanged", should_change=False, image=changing_input.out(0))
|
||||
g.node("SaveImage", images=test_node.out(0))
|
||||
|
||||
result1 = client.run(g)
|
||||
assert result1.did_run(test_node), "Node should run on first execution"
|
||||
assert result1.did_run(changing_input), "Input should run on first execution"
|
||||
|
||||
changing_input.set_input('content', "WHITE") # Change input content
|
||||
|
||||
result2 = client.run(g)
|
||||
assert result2.did_run(changing_input), "Input should re-execute due to content change"
|
||||
assert not result2.did_run(test_node), "Node with IS_CHANGED should NOT re-execute when IS_CHANGED is consistent"
|
||||
|
||||
# verify the behavior when IS_CHANGED actually changes
|
||||
test_node.set_input('should_change', True) # This should cause IS_CHANGED to return different value
|
||||
|
||||
result3 = client.run(g)
|
||||
assert result3.did_run(test_node), "Node should re-execute when IS_CHANGED value actually changes"
|
||||
|
||||
changing_input.set_input('content', "BLACK") # Change input back
|
||||
|
||||
result4 = client.run(g)
|
||||
assert result4.did_run(changing_input), "Input should re-execute due to content change"
|
||||
assert result4.did_run(test_node), "Node should re-execute because IS_CHANGED returns changing value (NaN)"
|
||||
|
||||
# This tests that nodes with OUTPUT_IS_LIST function correctly when they receive an ExecutionBlocker
|
||||
# as input. We also test that when that list (containing an ExecutionBlocker) is passed to a node,
|
||||
# only that one entry in the list is blocked.
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user