Skip to content

Recursive bounds inference can produce incorrect results in define_extern usage #1007

Open
@steven-johnson

Description

@steven-johnson

This is complicated to explain, so bear with me.

It's legal in Halide to have recursive bounds expressions for inputs to a Func; this can happen either explicitly, e.g.:

  in.set_extent(0, ((in.extent(0)+1)/2)*2)

or implicitly (e.g., as a result of using BoundaryConditions in the function definitions.

Unfortunately, when used in a multi-stage pipeline of realized functions (connected via define_extern), recursive bounds query expressions aren't always evaluated properly; in some cases, this can lead to pathological memory usage; in others, it can produce incorrect output.

I've attached an example of incorrect-output produced by this approach; in a nutshell, we have a toplevel pipeline that calls two define_extern()'ed functions; the "middle" function uses a BoundaryCondition that produces a recursive boundary condition for its input; when called in this pipeline, it ends up producing an "input required" that is always 1x1 pixel, regardless of the actual input size. (This basically means that all but that pixel in the output is essentially uninitialized).

This is a perplexing problem, as I don't know what the right answer is; in other fora, it's been suggested that the right way to handle bounds-query logic is to iterate until there's a stable answer, but this isn't what currently happens with define_extern() bounds queries, and even if it was, it's not clear whether it could be bounded effectively for all general cases.

bad_recursive_bounds_query.cpp.txt

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions