ComfyUI icon indicating copy to clipboard operation
ComfyUI copied to clipboard

[Feature Request] foreach loop / reducer

Open mnpenner opened this issue 1 year ago • 7 comments

It would be great if there was some way to loop over lists so that we can process things like "SEGS" (from Impact Pack) one item at a time. For example, I can detect all the faces an image and then output that to a list of masks. For each mask I want to upscale/enhance that part of the image and paste it into the image.

I was thinking about how this would look in the UI, and I realized this is exactly like a "reducer" in many programming languages. It could look like this:

image (The mockup in the screenshot is just a shell of a node)

On the left I have some node that produces a list, doesn't matter what, and that would go into the array input. item would output the first entry from the list/array, which I could process however I please, but it would most likely be merged into accum (accumulator), which would most likely be an output image (e.g. paste the enhanced face back into the image). Then you take that output and feed it back into the input accum of the Reduce node, thus forming a loop. Reduce then runs again with the next item in the input array and the updated accum, which repeats until the list is done, and then outputs the final result on final. init is the initial value for the output accum, for the first iteration of the loop. It's optional and will be None if not specified, just like a normal reduce function.

I would implement this myself as a custom node, but as far as I know I can't output/return more than once during a single "Queue Prompt" cycle like this node needs to do.

mnpenner avatar Apr 11 '24 03:04 mnpenner

Setting up a workflow in the style of a loop is not feasible within the current execution model. Instead, by combining the Backend Cache feature of the Inspire Pack and Auto Queue, it may be possible to utilize the Reduce node.

ltdrdata avatar Apr 11 '24 08:04 ltdrdata

I was hoping to avoid having to press queue more than once or use the Auto Queue feature because it makes transitioning to a new starter image more awkward, but if that's the best that can done for now I guess I'll have to make do. Thanks for the suggestion @ltdrdata

mnpenner avatar Apr 12 '24 02:04 mnpenner

I was hoping to avoid having to press queue more than once or use the Auto Queue feature because it makes transitioning to a new starter image more awkward, but if that's the best that can done for now I guess I'll have to make do. Thanks for the suggestion @ltdrdata

FYI, Impact Pack provides 'Queue Trigger' node. You can utilize it instead of auto queue.

ltdrdata avatar Apr 12 '24 02:04 ltdrdata

The "Queue Trigger" node is working is working great, but "Retrieve Backend Data" keeps throwing an error when there's no data, which will always be the case on the first iteration. I've set up a conditional (custom "If Zero") node so that it uses a different image for the first iteration, so I'd much rather Retrieve Backend Data just returns None instead of complaining it can't find the key. Do you know of a workaround for that?

image

mnpenner avatar Apr 12 '24 16:04 mnpenner

The "Queue Trigger" node is working is working great, but "Retrieve Backend Data" keeps throwing an error when there's no data, which will always be the case on the first iteration. I've set up a conditional (custom "If Zero") node so that it uses a different image for the first iteration, so I'd much rather Retrieve Backend Data just returns None instead of complaining it can't find the key. Do you know of a workaround for that?

image

Now it returns None instead of raise exception.

ltdrdata avatar Apr 13 '24 11:04 ltdrdata

It works perfectly now, thanks so much @ltdrdata !

mnpenner avatar Apr 15 '24 06:04 mnpenner