Infer the shapes of the output of a function based on the shapes of the input.
This works by running the function on the input and observing the results.
For fully known input shapes this is always correct.
For partially unknown shapes, the NAs are replaced with various concrete values
and the output shape is computed from them.
Note that this is a heuristic that might fail, so usually one wants to provide the shape
(inference) explicitly.
Arguments
- shapes_in
(
list())
A list of shapes of the input tensors.- param_vals
(
list())
A list of named parameters for the function.- output_names
(
character())
The names of the output tensors.- fn
(
function())
The function to infer the shapes for.- rowwise
(
logical(1))
Whether the function is rowwise.- id
(
character(1))
The id of the PipeOp (for error messages).
Value
(list())
A list of shapes of the output tensors.
Details
The inference is done as follows:
All
NAs are replaced with three different values, which span a wide range: none of them is1(which broadcasts and is squeezed away), one of them is small (to detect operators that clamp to the input size, such as slicing or cropping) and the others are large (because operators such as a convolution with a large kernel need a minimum extent).Three tensors are generated for the three shapes of step 1.
The function is called on these three tensors and the shapes are calculated. A call that fails is dropped, so that an operator is not rejected because of the smallest value; at least two of the three calls must succeed.
If:
the number of dimensions varies, an error is thrown.
the number of dimensions is the same, values are set to
NAif the dimension is varying between the tensors and otherwise set to the unique value.
See also
Other Shape Inference:
reshape_output_shape(),
shape_to_str()