Tensor Permute
Tensor Permute — reordering dimensions without touching the data
- tensor
- *
Tensor Permute is the node you reach for when your data is all there but sitting in the wrong order. A tensor's dimensions have a fixed sequence - say [batch, height, width, channels] - and permute rearranges that sequence without touching a single value. It's the difference between "my data is channel-last" and "my data is channel-first," and for anyone feeding tensors into models with a specific layout expectation, that difference is everything.
It's part of Basic data handling by StableLlama, a dependency-free utility pack that wraps everyday Python and PyTorch into ComfyUI nodes. Alongside Tensor Reshape and Tensor Slice, it's one of the shape-manipulation tools - and it's the one that reorders rather than repackages.
How it works
You type the new dimension order as a comma-separated string, and the node runs tensor.permute(...) with it. The string lists, for each position in the output, which dimension of the input to pull from.
Concretely: a ComfyUI image tensor is [batch, height, width, channels] - dims 0, 1, 2, 3. To convert it to channel-first [batch, channels, height, width], you permute to 0, 3, 1, 2:
- output dim 0 ← input dim 0 (batch)
- output dim 1 ← input dim 3 (channels)
- output dim 2 ← input dim 1 (height)
- output dim 3 ← input dim 2 (width)
The default 0, 1 is just the identity for a 2D tensor - a sensible default that does nothing until you change it.
The inputs that matter
Two inputs:
tensor(wildcard*) - the tensor to reorder.dims(STRING, default0, 1) - the new order, e.g.0, 3, 1, 2or2, 1, 0.
One wildcard output - the permuted tensor.
Where you'd actually use it
The flagship use case is layout conversion between the two great tensor religions: channel-last (HWC, what ComfyUI images are) and channel-first (CHW, what most PyTorch models and many custom node authors expect). When a custom node hands you data "in the wrong order," permute is how you fix it without re-copying anything. It's also how you flip a batch dimension to the front for batching, or move a time dimension around when working with video tensors.
A note on speed: permute doesn't copy data - it returns a view with a new stride layout, so it's cheap. You can use it freely in a graph without worrying about memory.
Installing it
# ComfyUI Manager (recommended): search "Basic data handling", install, restart.
# or manually:
cd ComfyUI/custom_nodes
git clone https://github.com/StableLlama/ComfyUI-basic_data_handling
# restart ComfyUI
No dependencies beyond torch, no model downloads.
Where people get burned
You must list every dimension. Permute is a full reorder, not a swap. Forgetting a dimension, or listing the wrong count, errors out - a 4D tensor needs exactly four numbers. If you only want to swap two dims on a larger tensor, you still have to write the whole order out (0, 2, 1, 3, say).
Permute is not transpose-in-the-broad-sense and not reshape. Transpose swaps two axes; permute reorders all of them. And critically, permute is not reshape - reshaping [B,H,W,C] to [B,C,H,W] scrambles your data into noise, while permute moves whole dimensions cleanly. When a tensor looks wrong after a shape change, this is the node you wanted all along.
The dims are a string, not a list input. A minor UI quirk: you type 0, 3, 1, 2 as text. Missing a comma or mistyping a number is the usual failure, and the error message will tell you the permutation is invalid - count your dims, re-read the string.
Inputs (2)
| Name | Type | Default | Description |
|---|---|---|---|
| tensor | * | — | |
| dims | STRING | 0, 1 | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| * | * | — |