Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

08: Control flow and host scalars

E0801

Value assigned in a loop or if changes its type. A loop or if block assigns a value from outside it, or a loop’s variable has the name of one, and the new value has a different shape, different axis names or a different dtype, is another model, or is another kind of host scalar. The code after the block, and the next iteration of a loop, must work either way, so only the value’s domain may change. Give the new value a new name.

dim D = 64

fn f(x: [b D], w: [D 2*D], n: int) -> [b D]:
    for i in 0..n:
        x = x @ w
    return x

See Blocks and scope.

E0802

if on something other than a bool. An if condition must be a bool, a [] Mask or a Python value. A mask with axes isn’t true or false: reduce it with any or all. A number must be compared with something, as in n > 0.

dim D = 64

fn f(x: [b D]) -> [b D]:
    if x > 0:
        x = x * 2
    return x

See Conditions.

E0803

Range whose ends aren’t ints. The ends of a..b in a for must be ints or Python values. A float isn’t one, and neither is a tensor, even a [] i64 one, since a range counts on the host.

dim D = 64

fn f(x: [b D], n: float) -> [b D]:
    for i in 0..n:
        x = x * 2
    return x

See Loops and Host scalars.

E0804

for over something that can’t be looped over. A for loops over a range, as in for i in 0..n:, over a dataset’s batches, as in for batch in train |> batches(64):, or over a Python value. A tensor can’t be looped over: index it in a loop over a range instead. A dataset is looped over a batch at a time.

dim D = 64

fn f(x: [n D]) -> [n D]:
    for row in x:
        x = x * 2
    return x

See Loops and Looping over batches.

E0805

Tensor where an int, float or bool is expected. A host scalar parameter, a host scalar return type, as int, as float or as bool, or the seed of init got a tensor or a model. Host scalars are Python values on the host; a tensor, even one of shape [], lives on the device, and reading it would wait for the device. There is no conversion from a tensor to a host scalar.

dim D = 64

fn scale(x: [b D], times: int) -> [b D]:
    for i in 0..times:
        x = x * 2
    return x

fn f(x: [b D]) -> [b D] = scale(x, sum(x) to i64)

See Host scalars.