Add an operation to expand a tensor. The operation expands the input tensor in the singleton dimensions to the size indicated by the corresponding dimension in the `expand_shape` tensor. In other words, given an input tensor with dimensions of size 1, those dimensions will be e
(input: Tensor, expand_shape: Tensor)
| 1570 | |
| 1571 | |
| 1572 | def expand(input: Tensor, expand_shape: Tensor) -> Tensor: |
| 1573 | ''' |
| 1574 | Add an operation to expand a tensor. |
| 1575 | |
| 1576 | The operation expands the input tensor in the singleton dimensions to the |
| 1577 | size indicated by the corresponding dimension in the `expand_shape` tensor. |
| 1578 | In other words, given an input tensor with dimensions of size 1, those |
| 1579 | dimensions will be expanded to the size in `expand_shape`. |
| 1580 | |
| 1581 | For example, a tensor of shape [4, 3, 1, 3] will be expanded to a tensor of |
| 1582 | shape [4, 3, 2, 3] by the layer created using expand(input, [4, 3, 2, 3]). |
| 1583 | |
| 1584 | The expansion may either replicate the values or be mapped to a view with a |
| 1585 | stride of 0 in the expanded dimensions. For example, for a tensor [[3, 2]] of |
| 1586 | shape [1, 2], |
| 1587 | |
| 1588 | expand([[3, 2]], [2, 2]) |
| 1589 | |
| 1590 | can be used to expand the input to [[3, 2], [3, 2]]. |
| 1591 | |
| 1592 | This operation is implemented using a tensorrt.ISliceLayer. The current |
| 1593 | implementation does not verify that non singleton dimensions are not |
| 1594 | shrunk. In other words, for an input of shape [4, 1, 2], |
| 1595 | |
| 1596 | expand(input, [3, 2, 2]) |
| 1597 | |
| 1598 | will produce a tensor of shape [3, 2, 2]. That behavior is subject to |
| 1599 | change in the future. |
| 1600 | |
| 1601 | Parameters: |
| 1602 | input : Tensor |
| 1603 | The input tensor. |
| 1604 | |
| 1605 | expand_shape : Tensor |
| 1606 | The new shape of the expanded tensor. |
| 1607 | |
| 1608 | Returns: |
| 1609 | The tensor produced by the expand layer. |
| 1610 | ''' |
| 1611 | ndim = input.rank() |
| 1612 | layer = default_trtnet().add_slice( |
| 1613 | input.trt_tensor, |
| 1614 | start=[0 for _ in range(ndim)], |
| 1615 | shape=[1 for _ in range(ndim)], # unused dummy value |
| 1616 | stride=[1 for _ in range(ndim)] # unused dummy value |
| 1617 | ) |
| 1618 | |
| 1619 | # The stride is either: |
| 1620 | # 0 for dimensions of size 1 (i.e. shape(input, i) - 1 == 1 - 1 == 0) or, |
| 1621 | # 1 for dimensions of size > 1 since minimum(value >= 1, 1) == 1. |
| 1622 | stride_tensor = concat( |
| 1623 | [minimum((shape(input, i) - 1), 1) for i in range(ndim)]) |
| 1624 | |
| 1625 | layer.set_input(2, expand_shape.trt_tensor) |
| 1626 | layer.set_input(3, stride_tensor.trt_tensor) |
| 1627 | return _create_tensor(layer.get_output(0), layer) |
| 1628 | |
| 1629 |
no test coverage detected