Conv2D
Convolve a tensor with a kernel — stride and padding included
- input_tensor
- kernel
- output
CdlConv2d performs a 2D convolution on an input tensor using a kernel you supply - with stride and padding controls, just like the real thing. It's a torch.nn.functional.conv2d wrapper, and it's the node you use when you want to perform a convolution by hand - slide a filter over data, watch the feature map come out - rather than declare a learned layer. If you're working through the "Dive into Deep Learning" material that ComfyDL is built on, this is the part where edge detection and blur kernels stop being abstract.
How it works
You feed it an input tensor and a kernel tensor. It handles the shape bookkeeping for you: a 2-D input is promoted to (1, 1, H, W) and a 3-D input gets a batch dimension, and a 2-D kernel becomes (1, 1, kH, kW) - so you don't have to manually insert the channel/batch dims that conv2d insists on. Then it calls F.conv2d with your stride and padding, and squeezes the batch dimension back out of the result.
The math: each output pixel is the sum of the element-wise product of the kernel with the corresponding input window. With stride 1 and padding 0, an H × W input and a k × k kernel give you (H − k + 1) × (W − k + 1). padding pads the input with zeros before the pass (keeping edges), stride jumps the window (downsampling). That's the whole mechanism, and it's identical to what a trained CNN does per-layer - the only difference is that here the kernel is a fixed tensor you chose, not learned weights.
Inputs and output
input_tensor- thecdlTensorto convolve.kernel- thecdlTensorfilter.stride- integer, 1–4, default 1.padding- integer, 0–10, default 0.
The output is output, a cdlTensor with the batch dimension removed.
What to do with it
Play. Drop a small image-like tensor in with a hand-picked kernel - a 3×3 edge-detector or blur - and see the feature map come out. That's the pedagogical sweet spot: it demystifies what CNN layers are actually computing. For building a real network, though, you'll use the model-level nodes (CdlLeNet, CdlResNet18, or the residual blocks) which own their learnable kernels; this node's job is understanding and poking, not training.
Installing it
It ships with ComfyDL, one install for the whole pack:
cd ComfyUI/custom_nodes
git clone https://github.com/Cynthia-lxx/ComfyDL
pip install -r ./ComfyDL/requirements.txt
Restart ComfyUI, or search "ComfyDL" in ComfyUI Manager.
Gotchas
- The kernel is an input, not a parameter. This is a functional convolution - there are no weights to train, and the node doesn't learn anything. Hand it the wrong kernel and you get the mathematically correct wrong answer.
- The result has the batch dimension squeezed off, so output shapes are
[C, H', W']-ish for 2-D-ish inputs. If you're chaining convs, account for that (and for theH − k + 1shrinkage on every unpadded pass - the classic reason feature maps keep shrinking). - Channels must line up with the kernel's channel count once expanded; mismatches fail with a raw PyTorch dimension error rather than a friendly message. If you see a confusing
expected 1 channeltype error, check the shapes you're feeding in.
Inputs (4)
| Name | Type | Default | Description |
|---|---|---|---|
| input_tensor | TENSOR | — | |
| kernel | TENSOR | — | |
| stride | INT | 11–4 | — |
| padding | INT | 00–10 | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| output | TENSOR | — |