Halide python API - interleaved image format support
11:31 04 Feb 2026

I wrote a simple Halide generator in python, and compiled it webAssembly. I want it to use interleaved RGB image data as input and output. Here is what it looks like:

import halide as hl

x = hl.Var('x')
y = hl.Var('y')
c = hl.Var('c')
 
@hl.generator(name="sample_generator")
class SampleGenerator:
    input = hl.InputBuffer(hl.UInt(8), 3)
    output = hl.OutputBuffer(hl.UInt(8), 3)
 
    def generate(self):
        self.output[x, y, c] = self.input[x, y, c]
 
        # Set buffer strides for input
        self.input.dim(0).set_stride(3)
        self.input.dim(2).set_stride(1)

        # Set buffer strides for output
        #   Test 1. Does not work since OutputBuffer does not have dim()
        # self.output.dim(0).set_stride(3)
        # self.output.dim(2).set_stride(1)
        #   Test 2. Set stride on output_buffer(). Runs fine, but still complain at runtime on contraint violated on output.stride.0 (3) == 1
        self.output.output_buffer().dim(0).set_stride(3)
        self.output.output_buffer().dim(2).set_stride(1)

In the JS call, I build a halide_buffer_t with 3 dimensions (eg (256, 256, 3) with strides (3, 256*3, 1). The code to create this halide_buffer_t is C++ exposed to webassembly:

halide_buffer_t* make_buffer(
    void *data,
    halide_type_t type,
    int dimensions,
    halide_dimension_t *dims
) {
    halide_buffer_t* buf = new halide_buffer_t{};
    buf->device = 0;
    buf->host = static_cast(data);
    buf->flags = 0;
    buf->type = type;
    buf->dimensions = dimensions;
    buf->dim = dims;
    buf->padding = nullptr;
    return buf;
}

template  halide_buffer_t* make_buffer(void* data, int dimensions, halide_dimension_t *dims) {
    // Just create a halide_type_t and forward dims
    // ...
    return make_buffer(data, type, dimensions, dims);
}

template 
halide_buffer_t* make_buffer_3d_interleaved(
    void *data,
    int width,
    int height,
    int channels
) {
    auto *dims = new halide_dimension_t[3];

    dims[0].min = 0;
    dims[0].extent = width;
    dims[0].stride = channels;
    dims[0].flags = 0;

    dims[1].min = 0;
    dims[1].extent = height;
    dims[1].stride = width * channels;
    dims[1].flags = 0;

    dims[2].min = 0;
    dims[2].extent = channels;
    dims[2].stride = 1;
    dims[2].flags = 0;

    return make_buffer(data, 3, dims);
}

As you can see, I tried several ways to give stride constraints to Halide in the generator with no luck.

In C++, this is my usual way to set such constraints. I also notice that if I run the generator from python using numpy arrays as inputs, everything goes fine, even if I set no constraints on data strides, so I believe Halide python runtime does the trick.

What is the correct way to use interleaved formats in this case ?
Thanks

python halide