LoopLevel#

class LoopLevel#

A reference to a site in a Halide statement at the top of the body of a particular for loop.

Evaluating a region of a halide function is done by generating a loop nest that spans its dimensions. We schedule the inputs to that function by recursively injecting realizations for them at particular sites in this loop nest. A LoopLevel identifies such a site. The site can either be a loop nest within all stages of a function or it can refer to a loop nest within a particular function’s stage (initial definition or updates).

Note that a LoopLevel is essentially a pointer to an underlying value; all copies of a LoopLevel refer to the same site, so mutating one copy (via the set() method) will effectively mutate all copies:

Func f;
Var x;
LoopLevel a(f, x);
// Both a and b refer to LoopLevel(f, x)
LoopLevel b = a;
// Now both a and b refer to LoopLevel::root()
a.set(LoopLevel::root());
This is quite useful when splitting Halide code into utility libraries, as it allows a library to schedule code according to a caller’s specifications, even if the caller hasn’t fully defined its pipeline yet:
Func demosaic(Func input,
             LoopLevel intermed_compute_at,
             LoopLevel intermed_store_at,
             LoopLevel output_compute_at) {
   Func intermed = ...;
   Func output = ...;
   intermed.compute_at(intermed_compute_at).store_at(intermed_store_at);
   output.compute_at(output_compute_at);
   return output;
}

void process() {
    // Note that these LoopLevels are all undefined when we pass them to demosaic()
    LoopLevel intermed_compute_at, intermed_store_at, output_compute_at;
    Func input = ...;
    Func demosaiced = demosaic(input, intermed_compute_at, intermed_store_at, output_compute_at);
    Func output = ...;

    // We need to ensure all LoopLevels have a well-defined value prior to lowering:
    intermed_compute_at.set(LoopLevel(output, y));
    intermed_store_at.set(LoopLevel(output, y));
    output_compute_at.set(LoopLevel(output, x));
}

Public Functions

int stage_index() const#

Return the index of the function stage associated with this loop level.

Asserts if undefined

LoopLevel(const Internal::Function &f, const VarOrRVar &v, int stage_index = -1)#

Identify the loop nest corresponding to some dimension of some function.

LoopLevel()#

Construct an undefined LoopLevel.

Calling any method on an undefined LoopLevel (other than set()) will assert.

LoopLevel(const std::string &func_name, const std::string &var_name, bool is_rvar, int stage_index, bool locked = false)#

For deserialization only.

void set(const LoopLevel &other)#

Mutate our contents to match the contents of ‘other’.

Public Static Functions

static LoopLevel inlined()#

Construct a special LoopLevel value that implies that a function should be inlined away.

static LoopLevel root()#

Construct a special LoopLevel value which represents the location outside of all for loops.